我正在学习这个,这是为了理解类的属性.但与以下代码片段的输出混淆.
class A:
aliases = None
name = None
def __init__(self,name):
self.name = name
self.aliases = set([name])
def add_aliases(self,a):
self.aliases.add(a)
def __repr__(self):
return str(self.name) + str(self.aliases)
arr = []
for i in range(3):
arr.append(A(i))
arr[-1].add_aliases(i+1)
for item in arr:
print item
A.aliases = set([]) ##Modify the static element of class
for item in arr:
print item
Run Code Online (Sandbox Code Playgroud)
Python解释器:2.7.9
输出是
0set([0, 1])
1set([1, 2])
2set([2, 3])
0set([0, 1])
1set([1, 2])
2set([2, 3])
Run Code Online (Sandbox Code Playgroud)
我期待这样的东西作为输出.
0set([2, 3])
1set([2, 3])
2set([2, 3])
0set([])
1set([])
2set([])
Run Code Online (Sandbox Code Playgroud)
并且解释是,当我们编写时,self.aliases = set([])我们实际上正在创建一个新的实例属性,遮蔽了类属性.
因此,如果我们__init__按照以下方式进行操作,我们就会获得预期的输出.
def __init__(self,name):
self.name = name
A.aliases = set([name]) #using the class attribute directly
Run Code Online (Sandbox Code Playgroud)
还请考虑以下代码段:
class A:
aliases = set([])
name = None
def __init__(self,name):
self.name = name
self.aliases.add(name) # using the class attribute indirectly.
def add_aliases(self,a):
self.aliases.add(a)
def __repr__(self):
return str(self.name) + str(self.aliases)
Run Code Online (Sandbox Code Playgroud)
因为在这种情况下,我们没有创建实例属性,所以没有阴影.问题中的测试代码会产生这样的输出:
0set([0, 1, 2, 3])
1set([0, 1, 2, 3])
2set([0, 1, 2, 3])
0set([])
1set([])
2set([])
Run Code Online (Sandbox Code Playgroud)
这是预期的,因为类属性在所有实例之间共享.
这里A.alias也可以称为self.alias内部init或任何其他功能.并且因为它没有遮蔽静态属性,所以给出了预期的输出 - 所有对象共享一个公共属性的情况.
同时采用一成不变的数据结构,就像一个人不知道这个概念不会注意到什么string等,但在数据结构的情况下,喜欢list和dictionary这样可能会感到惊讶.
还要考虑以下定义init.
def __init__(self,name):
self.name = name
self.aliases.add(name) # referring to class attribute
self.aliases = set([]) # creating a instance attribute
Run Code Online (Sandbox Code Playgroud)
而且这种情况也是如此,它最终创建instance attribute和测试代码产生的输出是:
0set([1])
1set([2])
2set([3])
0set([1])
1set([2])
2set([3])
Run Code Online (Sandbox Code Playgroud)
形成这一切我的学习是:
始终使用类名和实例属性引用类属性和对象名称,即A.aliases在表示类属性时写入aliases,不要写入self.aliases间接引用self.aliases
| 归档时间: |
|
| 查看次数: |
718 次 |
| 最近记录: |