Pet*_*ter 5 python initialization class-variables
我想将类的一些信息存储为类(静态)变量.但是,我无法弄清楚这些东西是如何初始化的.这是一个基本的,愚蠢的例子:
class A(object):
clsVar = 'a'
@classmethod
def clsMeth(cls):
print 'changing clsVar'
cls.clsVar = 'b'
A.clsMeth()
# prints 'changing clsVar'
print A.clsVar # prints 'a'
A.clsVar = 'b'
print A.clsVar # prints 'b'
Run Code Online (Sandbox Code Playgroud)
由于调用了函数(因为print语句有效),为什么类变量不会保持更改?如果在类定义完成后我不想这样做,我是否必须使用元类?
[具体来说,我想clsMeth成为一个装饰器,让类变量成为所有装饰的函数列表.我猜这不是实现这一目标的正确方法,所以我继续前进,但我仍然很好奇.
编辑:正如许多人所指出的,上面的代码将无法运行.我在IPython会话中运行它,其中调用A.clsMeth()将引用以前的版本A并运行.我想这就是使用解释性语言的风险.我结束了这样的事情:
outsideDict = {}
def outsideDec(func):
outsideDict[func.__name__] = func
class A(object):
@outsideDec
def someMethod(self):
print 'ID %s' % id(self)
def otherMethod(self):
print 'other'
print outsideDict
one, two = A(), A()
outsideDict['someMethod'](one)
outsideDict['someMethod'](two)
Run Code Online (Sandbox Code Playgroud)
也许这应该是另一个问题,但是当outsideDec运行时,有没有办法告诉它的论证是什么类?或者,有没有更好的方法在Python中进行这样的内省?我知道我在这里偏离正轨,所以我会接受下面的答案并做更多的研究.感谢大家!
A.clsMeth()定义中对 的调用A将不会运行,因为A此时不存在:
>>> class A(object):
... clsVar = 'a'
... @classmethod
... def clsMeth(cls):
... print 'changing clsVar'
... cls.clsVar = 'b'
... A.clsMeth()
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in A
NameError: name 'A' is not defined
Run Code Online (Sandbox Code Playgroud)
A如果之前已经定义了该代码(例如,如果您在 REPL 中对其进行测试),则该代码可能看起来可以工作,但是A.clsMeth对旧类的调用将在旧类上调用,而旧类将被新类所遮盖。
但是,我们绝对可以将该调用放在定义之后并获得您想要的结果:
>>> class A(object):
... clsVar = 'a'
... @classmethod
... def clsMeth(cls):
... print 'changing clsVar'
... cls.clsVar = 'b'
...
>>> A.clsMeth()
changing clsVar
>>> A.clsVar
'b'
Run Code Online (Sandbox Code Playgroud)
当然,正如 fabianhrj 所指出的,您也可以将其放入构造函数中,但在创建实例之前不会调用它。
| 归档时间: |
|
| 查看次数: |
11369 次 |
| 最近记录: |