Python def_uuuinit_uuuu(self)的有用性?
我对python相当陌生,并注意到以下帖子: 及 然而,在玩了它之后,我注意到这两个类给出了明显相同的结果-Python def_uuuinit_uuuu(self)的有用性?,python,Python,我对python相当陌生,并注意到以下帖子: 及 然而,在玩了它之后,我注意到这两个类给出了明显相同的结果- class A(object): def __init__(self): self.x = 'Hello' def method_a(self, foo): print self.x + ' ' + foo (来自) 及 这两者之间有什么真正的区别吗?或者,更一般地说,\uuuu init\uuu是否会改变类的属性?其中提到在创建实例
class A(object):
def __init__(self):
self.x = 'Hello'
def method_a(self, foo):
print self.x + ' ' + foo
(来自)
及
这两者之间有什么真正的区别吗?或者,更一般地说,\uuuu init\uuu
是否会改变类的属性?其中提到在创建实例时调用\uuuu init\uuu
。这是否意味着类B
中的x
是在实例化之前建立的 是的,看看这个:
class A(object):
def __init__(self):
self.lst = []
class B(object):
lst = []
现在试试:
>>> x = B()
>>> y = B()
>>> x.lst.append(1)
>>> y.lst.append(2)
>>> x.lst
[1, 2]
>>> x.lst is y.lst
True
这是:
>>> x = A()
>>> y = A()
>>> x.lst.append(1)
>>> y.lst.append(2)
>>> x.lst
[1]
>>> x.lst is y.lst
False
这是否意味着类B中的x是在实例化之前建立的
是的,它是一个类属性(在实例之间共享)。而在类A中,它是一个实例属性。碰巧字符串是不可变的,因此在您的场景中没有真正的区别(除了类B使用更少的内存,因为它只为所有实例定义一个字符串)。但是在我的示例中有一个很大的例子。在第一个示例中,您有类实例的变量。此变量只能通过实例访问(自选) 在第二个示例中,您有一个静态变量。由于类A的名称,您可以访问此变量
class A():
x = 'hello'
print A.x -> 'hello'
print A().x -> 'hello'
事实上,您可以使用相同名称的静态变量和实例变量:
class A():
x = 'hello'
def __init__(self):
self.x = 'world'
print A.x -> hello
print A().x -> world
静态值在所有实例之间共享
class A():
x = 'hello'
@staticmethod
def talk():
print A.x
a = A()
print a.talk() -> hello
A.x = 'world'
print a.talk() -> world
你在这里有一篇好文章:
正如其他人所说,它是类上的变量和类实例上的变量之间的区别。请参见下面的示例
>>> class A:
... a = []
...
>>> class B:
... def __init__(self):
... self.b = []
...
>>> a1 = A()
>>> a1.a.append('hello')
>>> a2 = A()
>>> a2.a
['hello']
>>> b1 = B()
>>> b1.b.append('goodbye')
>>> b2 = B()
>>> b2.b
[]
对于元组、字符串等不可变对象,很难注意到它们之间的区别,但对于可变对象,它会更改所有应用的更改,这些更改在该类的所有实例之间共享
还要注意,关键字参数默认值也会发生相同的行为
>>> class A:
... def __init__(self, a=[]):
... a.append('hello')
... print(a)
...
>>> A()
['hello']
>>> A()
['hello', 'hello']
>>> A()
['hello', 'hello', 'hello']
>>> class B:
... def __init__(self, b=None):
... if b is None:
... b = []
... b.append('goodbye')
... print(b)
...
>>> B()
['goodbye']
>>> B()
['goodbye']
>>> B()
['goodbye']
这种行为让许多新的Python程序员感到厌烦。在早期发现这些区别对你有好处 +1不要忘记,因为类是对象,所以您可以随时更改类本身的属性<代码>A类:合格;A.lst=列表(范围(6))。另请参见
>>> class A:
... a = []
...
>>> class B:
... def __init__(self):
... self.b = []
...
>>> a1 = A()
>>> a1.a.append('hello')
>>> a2 = A()
>>> a2.a
['hello']
>>> b1 = B()
>>> b1.b.append('goodbye')
>>> b2 = B()
>>> b2.b
[]
>>> class A:
... def __init__(self, a=[]):
... a.append('hello')
... print(a)
...
>>> A()
['hello']
>>> A()
['hello', 'hello']
>>> A()
['hello', 'hello', 'hello']
>>> class B:
... def __init__(self, b=None):
... if b is None:
... b = []
... b.append('goodbye')
... print(b)
...
>>> B()
['goodbye']
>>> B()
['goodbye']
>>> B()
['goodbye']