关于oop:python-为什么在类中使用”self”?

Python - why use “self” in a class?

这两类有什么不同?

1
2
3
4
5
6
class A():
    x=3

class B():
    def __init__(self):
        self.x=3

有什么显著的区别吗?


A.x是一个类变量。Bself.x是一个实例变量。

Ax在实例之间共享。

用一些可以修改的东西(如列表)来演示差异会更容易:

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
#!/usr/bin/env python

class A:
    x = []

    def add(self):
        self.x.append(1)


class B:
    def __init__(self):
        self.x = []

    def add(self):
        self.x.append(1)


x = A()
y = A()
x.add()
y.add()
print"A's x:",x.x

x = B()
y = B()
x.add()
y.add()
print"B's x:",x.x

产量

A's x: [1, 1]
B's x: [1]


附带说明:self实际上只是一个随机选择的单词,每个人都使用,但是你也可以使用thisfoomyself或任何你想要的东西,它只是一个类的每个非静态方法的第一个参数。这意味着单词self不是语言结构,而是一个名称:

1
2
3
4
5
6
7
8
>>> class A:
...     def __init__(s):
...        s.bla = 2
...
>>>
>>> a = A()
>>> a.bla
2


a.x是一个类变量,将在a的所有实例之间共享,除非在实例中特别重写。b.x是一个实例变量,b的每个实例都有自己的版本。

我希望下面的python示例可以澄清:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    >>> class Foo():
    ...     i = 3
    ...     def bar(self):
    ...             print 'Foo.i is', Foo.i
    ...             print 'self.i is', self.i
    ...
    >>> f = Foo() # Create an instance of the Foo class
    >>> f.bar()
    Foo.i is 3
    self.i is 3
    >>> Foo.i = 5 # Change the global value of Foo.i over all instances
    >>> f.bar()
    Foo.i is 5
    self.i is 5
    >>> f.i = 3 # Override this instance's definition of i
    >>> f.bar()
    Foo.i is 5
    self.i is 3

我用这个例子来解释它

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
# By TMOTTM

class Machine:

    # Class Variable counts how many machines have been created.
    # The value is the same for all objects of this class.
    counter = 0

    def __init__(self):

        # Notice: no 'self'.
        Machine.counter += 1

        # Instance variable.
        # Different for every object of the class.
        self.id = Machine.counter

if __name__ == '__main__':
    machine1 = Machine()
    machine2 = Machine()
    machine3 = Machine()

    #The value is different for all objects.
    print 'machine1.id', machine1.id
    print 'machine2.id', machine2.id
    print 'machine3.id', machine3.id

    #The value is the same for all objects.
    print 'machine1.counter', machine1.counter
    print 'machine2.counter', machine2.counter
    print 'machine3.counter', machine3.counter

然后输出将

1
2
3
4
5
6
7
machine1.id 1
machine2.id 2
machine3.id 3

machine1.counter 3
machine2.counter 3
machine3.counter 3

我刚开始学习Python,这让我困惑了一段时间。为了弄清楚它是如何工作的,我想出了一个非常简单的代码:

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
# Create a class with a variable inside and an instance of that class
class One:
    color = 'green'

obj2 = One()


# Here we create a global variable(outside a class suite).
color = 'blue'        

# Create a second class and a local variable inside this class.      
class Two:            
    color ="red"

    # Define 3 methods. The only difference between them is the"color" part.
    def out(self):    
        print(self.color + '!')

    def out2(self):
        print(color + '!')

    def out3(self):
        print(obj2.color + '!')

# Create an object of the class One
obj = Two()

当我们调用out()时,我们得到:

1
2
3
>>> obj.out()

red!

当我们称之为out2()时:

1
2
3
>>> obj.out2()

blue!

当我们称之为out3()时:

1
2
3
>>> obj.out3()

green!

因此,在第一个方法中,self指定python应该使用变量(attribute),即"属于"我们创建的类对象,而不是全局对象(类外部)。所以它使用了color ="red"。在方法中,python隐式地将self替换为我们创建的对象的名称(obj)。self.color的意思是"我要从obj那里得到color="red""

在第二种方法中,没有self来指定应该从中获取颜色的对象,因此它得到全局的color = 'blue'

在第三种方法中,我们使用了obj2,而不是self,这是从另一个对象的名称来获取color。它得到了color = 'green'