我想将有关类的一些信息存储为类(静态)变量。但是,我不知道如何初始化这些东西。这是一个简单的基本示例:
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'
由于调用了该函数(当print语句起作用时),为什么类变量保持不变?如果在类定义完成后不想这样做,是否必须使用元类?
[具体来说,我希望
clsMeth
成为装饰器,并让class变量成为所有经过如此装饰的函数的列表。我猜想这不是实现此目标的正确方法,所以我继续前进,但我仍然很好奇。编辑:正如许多人指出的那样,上面的代码将无法运行。我在IPython session 中运行它,对
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)
也许这应该是另一个问题,但是当
outsideDec
运行时,是否有办法告诉其参数属于哪个类?还是在Python中有更好的自省(introspection)方法?我知道我在这里偏离方向,所以我将接受下面的答案并做更多的研究。谢谢大家! 最佳答案
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
如果先前已经定义了
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'
当然,正如fabianhrj指出的那样,您也可以将其放在构造函数中,但是只有在创建实例后才可以调用它。