Python类变量初始化

时间:2011-12-14 18:32:11

标签: 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'

由于函数被调用(因为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中进行这样的内省?我知道我在这里偏离正轨,所以我会接受下面的答案并做更多的研究。谢谢大家!

2 个答案:

答案 0 :(得分:4)

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所指出的那样,你也可以把它放在构造函数中,但是在创建实例之前不会调用它。

答案 1 :(得分:0)

您需要将所有语句放在函数中才能使它们起作用。我建议如果你想在创建对象时运行某些东西,只需将它放在构造函数中。

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

我们有。