Class python 上下文中的变量 class
Class variable in python context class
我正在编写一系列嵌套上下文,需要跟踪它们的相对关系。但是我 运行 以下行为是我没想到的:
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
断言失败,因为 class 变量 _current
是 None,这是意外的,因为我认为 __enter__
只是将其设置为 self。这似乎与我不理解的 Python 上下文的一些更深层次的行为有关。谁能解释一下?谢谢。
您正在测试 class 属性。您设置 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搜索实例层,class和基础层classes。但是当设置一个属性时,就不会发生这样的分层。因此,如果 self
上没有这样的属性,self._current
将退回到 NestedContext
,但是 self._current = some_value
在 self
上设置该属性,而不是 [=42] =].
我还使用 object
作为 NestedContext
的父 class;除非有令人信服的理由不这样做(例如,您正在使用依赖于旧行为的遗留代码),否则您总是希望获得 new style classes.
演示(添加了 _name
属性和 __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')>
我正在编写一系列嵌套上下文,需要跟踪它们的相对关系。但是我 运行 以下行为是我没想到的:
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
断言失败,因为 class 变量 _current
是 None,这是意外的,因为我认为 __enter__
只是将其设置为 self。这似乎与我不理解的 Python 上下文的一些更深层次的行为有关。谁能解释一下?谢谢。
您正在测试 class 属性。您设置 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搜索实例层,class和基础层classes。但是当设置一个属性时,就不会发生这样的分层。因此,如果 self
上没有这样的属性,self._current
将退回到 NestedContext
,但是 self._current = some_value
在 self
上设置该属性,而不是 [=42] =].
我还使用 object
作为 NestedContext
的父 class;除非有令人信服的理由不这样做(例如,您正在使用依赖于旧行为的遗留代码),否则您总是希望获得 new style classes.
演示(添加了 _name
属性和 __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')>