Analysis of __init__() and self in Python class

1. The meaning of self in Python

self, the meaning of the English word is obvious, expressing oneself, itself.

There are several potential implications here:

1. The self here refers to the instance instance itself.

2. At the same time, since the word "self" is mentioned in relation to "others"; and the others here refer to the class Class and other variables, such as local variables and global variables wait.

The self here is an object (Object), which is an instance of the current class.

Therefore, the valueName in the corresponding self.valueName and self.function(): represents the self object, that is, the variable of the instance. Corresponding to others, Class variables, global variables, and local variables.

function: Indicates that the self object is called, that is, the function of the instance. It corresponds to other global functions.

2. Why is there a self in Python

That is:

In the code (function) of the class, it is necessary to access the variables and functions in the current instance, that is, to access the Instance:

  • Corresponding variable (property, property): Instance.ProperyNam, to read the previous value and write the new value

  • Call the corresponding function (function): Instance.function(), that is, execute the corresponding action

-> But you need to access the variables of the instance and call the function of the instance, of course, you need the corresponding instance Instance object itself

-> In Python, it is stipulated that the first parameter of the function must be the instance object itself, and it is recommended that, by convention, write its name as self

-> So, we need self (need to use self)

And if self is not used, that is, after removing self in the code, the variables used in that writing method are actually not what you want, not the variables and functions in the real instance, but access to other parts variables and functions too. It can even lead to subsequent inaccessible errors due to not properly initializing instance variables.

Below, the code is used to demonstrate what errors will occur if self is removed or self is not used properly.

3. First look at __init__() and the self object

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author: antcolonies

class Person(object):

    def __init__(self, name, lang, website):

        self.name = name

        self.lang = lang

        self.website = website

        print('self: 'self)

        print('type of self: 'type(self))

'''

未实例化时,运行程序,构造方法没有运行

'''

= Person('Tim''English''www.universal.com')   

'''实例化后运行的结果

self:  <__main__.Person object at 0x00000000021EAF98>

type of self:  <class '__main__.Person'>

'''

可以看出self为实例变量p,是一个Person类型的对象。

1

2

3

4

5

6

7

8

9

10

11

class Dog(object):       

    def __init__(self,name,dog_type):

        self.name = name

        self.type = dog_type

   

    def sayhi(self):

        print("hello,I am a dog, my name is ",self.name)

   

   

= Dog('LiChuang',"京巴")            # 实例化

d.sayhi()

以下是d = Dog('LiChuang',"京巴")实例化的示意图:

4、如果没有在__init__中初始化对应的实例变量的话,导致后续引用实例变量会出错

如下代码,完整的演示了,如果没有在类Class的最初的__init__函数中,正确的初始化实例变量,则会导致后续没有变量可用,因而出现AttributeError的错误:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author: antcolonies

name = 'whole global name'

'''

注:此处全局的变量名,写成name,只是为了演示而用

实际上,好的编程风格,应该写成gName之类的名字,

以表示该变量是Global的变量

'''

class Person(object):

    def __init__(self, newPersonName):

        # self.name = newPersonName

        '''

        如果此处不写成self.name

        那么此处的name,只是__init__函数中的局部临时变量name而已

        和全局中的name,没有半毛钱关系

        '''

        name = newPersonName

        '''

        此处只是为了代码演示,而使用了局部变量name,

        不过需要注意的是,此处很明显,由于接下来的代码也没有利用到此处的局部变量name

        则就导致了,此处的name变量,实际上被浪费了,根本没有利用到

        '''

    def sayYourName(self):

        '''

        此处由于找不到实例中的name变量,所以会报错:

        AttributeError: Person instance has no attribute 'name'

        '''

        print('My name is %s' %self.name)

def selfAndInitDemo():

    personInstance = Person('Tim')

    personInstance.sayYourName()

if __name__ == '__main__':

    selfAndInitDemo()

'''  未使用self.name时抛异常

Traceback (most recent call last):

  File "E:/python14_workspace/s14/day06/test_1.py", line 18, in <module>

    selfAndInitDemo()

  File "E:/python14_workspace/s14/day06/test_1.py", line 15, in selfAndInitDemo

    personInstance.sayYourName()

  File "E:/python14_workspace/s14/day06/test_1.py", line 11, in sayYourName

    print('My name is %s' %self.name)

AttributeError: 'Person' object has no attribute 'name'

'''

从上述代码可见,由于在类的初始化(实例化)的__init__函数中,没有给self.name设置值,使得实例中,根本没有name这个变量,导致后续再去访问self.name,就会出现AttributeError的错误了。

对应的,如果写成self.name,则意思就正确了,就是初始化的时候,给实例中新增加,并且正常设置了正确的值newPersionName了,所以后续再去通过self.name,就可以访问到,当前实例中正确的变量name了。

相应的正确写法的代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author: antcolonies

name = 'whole global name'

'''

注:此处全局的变量名,写成name,只是为了演示而用

实际上,好的编程风格,应该写成gName之类的名字,

以表示该变量是Global的变量

'''

class Person(object):

    def __init__(self, newPersonName):

        self.name = newPersonName

        '''

        此处正确的,通过访问self.name的形式,实现了:

            1.给实例中,增加了name变量

            2.并且给name赋了初值,为newPersionName

        '''

    def sayYourName(self):

        '''

        此处由于开始正确的初始化了self对象,使得其中有了name变量,

        所以此处可以正确访问了name值了

        '''

        print('My name is %s' %self.name)

def selfAndInitDemo():

    personInstance = Person('Tim')

    personInstance.sayYourName()

if __name__ == '__main__':

    selfAndInitDemo()

'''My name is Tim'''

5、在函数中,使用对应的变量,虽然代码是可以运行的,但是实际上却是使用的,不是实例中的变量

有时候,虽然你写的代码,可以运行,但是使用到的变量,由于没有加self,实际上是用到的不是实例的变量,而是其他的变量。

此类问题,主要和Python中的变量的作用域有关,但是此处例子中,也和是否使用self有关:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# Author: antcolonies

name = 'whole global name'

'''

注:此处全局的变量名,写成name,只是为了演示而用

实际上,好的编程风格,应该写成gName之类的名字,

以表示该变量是Global的变量

'''

class Person(object):

    name = 'class global name'

    def __init__(self, newPersonName):

        # self.name = newPersonName

        '''

        此处,没有使用self.name

        而使得此处的name,实际上仍是局部变量name

        虽然此处赋值了,但是后面没有被利用到,属于被浪费了的局部变量name

        '''

        name = newPersonName

    def sayYourName(self):

        '''

        此处,之所以没有像之前一样出现:

        AttributeError: Person instance has no attribute 'name'

        那是因为,虽然当前的实例self中,没有在__init__中初始化对应的name变量,实例self中没有对应的name变量

        但是由于实例所对应的类Person,有对应的name变量,所以也是可以正常执行代码的

        对应的,此处的self.name,实际上是Person.name

        '''

        print('My name is %s' %self.name)

        print('Name within class Person is actually the global name: %s' %name)

        print("Only access Person's name via Person.name = %s" %(Person.name))

def selfAndInitDemo():

    personInstance = Person('Tim')

    personInstance.sayYourName()

    print('whole global name is %s' %name)

if __name__ == '__main__':

    selfAndInitDemo()

'''

My name is class global name

Name within class Person is actually the global name: whole global name

Only access Person's name via Person.name = class global name

whole global name is whole global name

'''

其中,可见,此处开始__init__中,没有给self实例初始化对应的name,

而后面的函数sayYourName中,虽然可以调用到self.name而没有出现AttributeError错误,

但是实际上此处的值,不是所期望的,传入的name,即"Tim",而是类中的name的值,即"class global name"。

 

Guess you like

Origin blog.csdn.net/m0_72557783/article/details/128486851