2011-12-14 159 views
5

我想将类的一些信息存储为类(静态)变量。但是,我无法弄清楚这些东西是如何初始化的。这是一个基本的,愚蠢的例子:Python类变量初始化

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是一个装饰器,并且让类变量成为所有装饰过的函数的列表。我猜这是不正确的方式去完成,所以我已经走了,但我仍然好奇。]

编辑:许多人指出,上面的代码赢得'运行。我在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) 

或许,这应该是一个问题,但是当outsideDec获取运行,有没有办法告诉它就是类的说法是会员吗?或者有没有更好的方式在Python中做这样的内省?我承认我在这里转向课程,所以我会接受下面的答案并做更多的研究。感谢大家!

+0

我得到的是调用`A.clsMeth`时发生错误,因为`A`未定义。也许你在使用解释器,并且你有一个旧的`A`定义? – jcollado 2011-12-14 18:45:51

+0

你如何运行这个示例?这不能工作,因为语法不正确。 `A.clsMth()`不能像这样放在类定义中。 – gecco 2011-12-14 18:47:28

回答

4

A定义将不会运行到A.clsMeth()的调用,为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指出,你可以把它在构造函数中一样好,但它赢得了”直到你创建一个实例才会被调用。

0

你需要把所有的语句放在一个函数中才能工作。我建议如果你想在创建对象时运行某些东西,只需将它放在构造函数中即可。

class A: 
    def clsMeth(self): 
     print("Changing clsVar") 
     self.clsVar = 'b' 
    def __init__(self): 
     self.clsMeth() 
    clsVar = 'a' 

我们在那里。