python上下文类中的类变量

时间:2015-01-17 09:41:50

标签: python python-2.7

我正在编写一系列嵌套的上下文,需要跟踪它们的相对关系。但我遇到了以下我没想到的行为:

class NestedContext():
    _current = None
    def __enter__(self):
        self.parent = self._current
        self._current = self

    def __exit__(self, _type, _value, _tb):
         self._current = self.parent

with NestedContext():
    assert NestedContext._current is not None # fails
    with NestedContext():
        pass

断言失败,因为类变量_current是None,这是意料之外的,因为我认为__enter__只是将它设置为self。这似乎与我不理解的Python上下文的一些更深层次的行为有关。谁能解释一下?感谢。

1 个答案:

答案 0 :(得分:5)

您正在测试类属性。您设置self._current实例属性

如果您想设置class属性,则需要对其进行限定:

class NestedContext(object):
    _current = None

    def __enter__(self):
        self.parent = self._current
        NestedContext._current = self

    def __exit__(self, _type, _value, _tb):
         NestedContext._current = self.parent

读取属性时,Python会搜索实例,类和基类的层。但是当设置属性时,不会发生这样的分层。因此self._current如果NestedContext上没有此类属性,self会回退到self._current = some_value,但self会在object上设置该属性,而不是在类上。< / p>

我还使用NestedContext作为_name的父类;除非有令人信服的理由(例如,您正在处理依赖于旧行为的遗留代码),否则您总是希望获得new style classes

演示(添加__repr__属性和>>> class NestedContext(object): ... _current = None ... def __init__(self, name): ... self._name = name ... def __repr__(self): ... return '<NestedContext({._name!r})>'.format(self) ... def __enter__(self): ... self.parent = self._current ... NestedContext._current = self ... def __exit__(self, _type, _value, _tb): ... NestedContext._current = self.parent ... >>> with NestedContext('outer'): ... print NestedContext._current ... with NestedContext('inner'): ... print NestedContext._current ... print NestedContext._current.parent ... <NestedContext('outer')> <NestedContext('inner')> <NestedContext('outer')> 方法):

{{1}}