use*_*609 5 python python-2.7 python-internals
我正在查看Stack Overflow问题计算类的实例?,我不确定为什么该解决方案有效,而使用简单添加的解决方案则不然.我想这更像是一个关于如何存储和访问类与实例变量的问题.
这是我认为应该起作用的代码,但代之以4为id:
class foo():
num = 3 # trying 3 instead of 0 or 1 to make sure the add is working
def __init__(self):
self.num += 1
self.id = self.num
f = foo()
g = foo()
print f.id # 4
print g.id # 4
Run Code Online (Sandbox Code Playgroud)
该self.num +=1声明有些工作(增加正在发生,但不是作业).
正在进行这项任务的情况下发生的事情在这里失败,而itertools.count任务在另一个问题的解决方案中成功了吗?
self.num += 1基本上是指“取的值self.num,将其递增,然后分配给” self.num。
self如果没有相应的实例变量,则在其上查找属性将找到类变量。但是,分配将始终写入实例变量。因此,这尝试查找实例var,失败,退回到类var,获取值,将其递增,然后分配给实例var。
链接问题的答案起作用的原因是因为没有分配正在进行;他们next()直接在类变量上调用,其值被更改,但未重新分配名称。
整数不实现__iadd__(就地添加,for +=),因为它们是不可变的.解释器回退到标准分配__add__,所以行:
self.num += 1
Run Code Online (Sandbox Code Playgroud)
变为:
self.num = self.num + 1
Run Code Online (Sandbox Code Playgroud)
在右侧,你得到foo.num(即3)via self.num,如你所料,但这里有趣的是分配给instance属性num 阴影 class属性.所以这条线实际上相当于:
self.num = foo.num + 1 # instance attribute equals class attribute plus one
Run Code Online (Sandbox Code Playgroud)
所有的情况下结束了self.num == 4和类保持foo.num == 3.相反,我怀疑你想要的是:
foo.num += 1 # explicitly update the class attribute
Run Code Online (Sandbox Code Playgroud)
或者,您可以将其实现为a @classmethod,更明确地处理类:
class Foo(): # note naming convention
num = 3
def __init__(self):
self.increment()
self.id = self.num # now you're still accessing the class attribute
@classmethod
def increment(cls):
cls.num += 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1580 次 |
| 最近记录: |