2012-10-10 93 views
0

使用self.variable语法创建变量和创建一个变量之间有什么区别?在Python类中,使用自身语法创建变量和创建一个变量之间有什么区别?

我测试出来,我仍然可以从一个实例访问两个:

class TestClass(object): 
    j = 10 
    def __init__(self): 
     self.i = 20 

if __name__ == '__main__': 
    testInstance = TestClass() 
    print testInstance.i 
    print testInstance.j 

但是,如果我换了self的位置,会导致错误。

class TestClass(object): 
    self.j = 10 
    def __init__(self): 
     i = 20 

if __name__ == '__main__': 
    testInstance = TestClass() 
    print testInstance.i 
    print testInstance.j 

>>NameError: name 'self' is not defined 

所以我推测,自己在初始化一个特殊的角色..但是,我只是不太明白是什么。

回答

6

self指类的当前实例。如果在函数体外部声明一个变量,则表示该类本身,而不是实例,因此该类的所有实例将共享该属性的相同值。

另外,声明为类的一部分(而不是一个实例的一部分)的变量可以作为类本身的一部分进行访问:

class Foo(object): 
    a = 1 

one = Foo() 
two = Foo() 

Foo.a = 3 

由于该值是类宽,不仅可以你直接从类阅读:

print Foo.a # prints 3 

但它也将改变值类的每一个实例:

print one.a # prints 3 
print two.a # prints 3 

但是,请注意,只有在不使用实例变量覆盖类变量的情况下才会出现这种情况。例如,如果你创建了以下内容:

class Bar(object) 
    a = 1 
    def __init__(self): 
     self.a = 2 

,然后做了以下:

one = Bar() 
two = Bar() 
two.a = 3 

然后你会得到如下结果:

print Bar.a # prints "1" 
print one.a # prints "2" 
print two.a # prints "3" 

正如评论指出,分配给​​将在该实例上创建一个实例本地条目,该条目将从Bar覆盖a,因此Bar.a为什么是还是1,但​​为3

+0

由于'了'是一个类变量,你也可以访问'美孚.a'直接 –

+0

@NathanVillaescusa非常真实。 – Amber

+0

另一件事,如果foo的'__init__'方法,你改变'self.a',你该实例这么做而已,所以'Foo.a'依然不变。 –

0

对于方法,您有类实例本身传递的第一个参数

def TestClass(object): 
    def foo(self, x): 
    pass 

thing = TestClass() 
thing.foo("hello") 

#^
# |__ this will call the bound method `foo()`, passing in thing as the first 
#  argument and "hello" as the second argument 

使用名称self就是一个Python约定,它将如果你无论如何发生使用一些其他的名字。

在第二个示例中,self根本没有定义,因此请求self.j没有任何意义,这就是为什么你会看到你得到的错误。

0

j是Amber指出的类变量。现在,如果你来自C++背景,self类似于this指针。虽然蟒蛇不指针处理,self起到参考类的当前实例的类似的作用。

在Python方式,explicit is better than implicit。在C++中,通常假定每个类别都有this的可用性。另一方面,Python明确地将self作为第一个参数传递给每个实例方法。

因此self仅在您的实例方法的范围内可用,因此它为undefined表示您尝试使用它的位置。

既然你做出明确地传递给self实例方法,你也可以把它的东西,如果你想别的事情 -

>>> class Foo: 
...  b = 20 
...  def __init__(them): 
...    them.beep = "weee" 
... 
>>> f = Foo() 
>>> f.beep 
'weee' 
相关问题