Class 属性 返回 属性 对象
Class property returning property object
在这被标记为重复之前,我以前就知道这个 question has been answered,但那里提供的解决方案似乎不适用于我的情况。我正在尝试以编程方式设置 class 属性。我知道我可以为此使用 property
,所以我考虑过这样做:
class Foo:
def __init__(self, x):
self._x = x
def getx(): return self._x
def setx(y): self._x = y
self.x = property(fget=getx, fset=setx)
但是,当我 运行 以交互方式进行此操作时,我得到:
>>> f = Foo(42)
>>> f.x
<property object at 0x0000000>
>>> f._x
42
>>> f.x = 1
>>> f.x
1
有什么办法可以解决吗?
编辑:
我觉得我可能遗漏了太多,所以这就是我真正想要达到的目标。我有一个 class 和一个名为 config
的 class 变量,它包含要设置为属性的配置值。 class 应该被子classed 以实现 config
变量:
class _Base:
config = ()
def __init__(self, obj, **kwargs):
self._obj = obj()
for kwarg in kwargs:
# Whatever magic happens here to make these properties
# Sample implementation
class Bar(_Base):
config = (
"x",
"y"
)
def __init__(self, obj, x, y):
super().__init__(obj, x=x, y=y)
现在允许操作:
>>> b = Bar(x=3, y=4)
>>> b.x
3
>>> # Etc.
我尽量保持干燥,因为我必须经常使用 subclass _Base
。
property
对象是 descriptors,描述符仅在 class 或 metaclass 上定义时调用。您不能将它们直接放在实例上; __getattribute__
classes 的实现根本不调用所需的绑定行为。
您需要将 属性 放在 class 上,而不是在每个实例上:
class Foo:
def __init__(self, x):
self._x = x
@property
def x(self): return self._x
@x.setter
def x(self, y): self._x = y
如果你必须有一个只适用于某些情况的 属性,你将不得不改变你的 getter 和 setter 方法来改变行为(比如引发 AttributeError
因为当实例的状态是属性应该 'not exist').
class Bar:
def __init__(self, has_x_attribute=False):
self._has_x_attribute = has_x_attribute
self._x = None
@property
def x(self):
if not self._has_x_attribute:
raise AttributeError('x')
return self._x
@x.setter
def x(self, y):
if not self._has_x_attribute:
raise AttributeError('x')
self._x = y
property
对象仍然存在并被绑定,但当标志设置为 false 时,其行为就好像该属性不存在一样。
在这被标记为重复之前,我以前就知道这个 question has been answered,但那里提供的解决方案似乎不适用于我的情况。我正在尝试以编程方式设置 class 属性。我知道我可以为此使用 property
,所以我考虑过这样做:
class Foo:
def __init__(self, x):
self._x = x
def getx(): return self._x
def setx(y): self._x = y
self.x = property(fget=getx, fset=setx)
但是,当我 运行 以交互方式进行此操作时,我得到:
>>> f = Foo(42)
>>> f.x
<property object at 0x0000000>
>>> f._x
42
>>> f.x = 1
>>> f.x
1
有什么办法可以解决吗?
编辑:
我觉得我可能遗漏了太多,所以这就是我真正想要达到的目标。我有一个 class 和一个名为 config
的 class 变量,它包含要设置为属性的配置值。 class 应该被子classed 以实现 config
变量:
class _Base:
config = ()
def __init__(self, obj, **kwargs):
self._obj = obj()
for kwarg in kwargs:
# Whatever magic happens here to make these properties
# Sample implementation
class Bar(_Base):
config = (
"x",
"y"
)
def __init__(self, obj, x, y):
super().__init__(obj, x=x, y=y)
现在允许操作:
>>> b = Bar(x=3, y=4)
>>> b.x
3
>>> # Etc.
我尽量保持干燥,因为我必须经常使用 subclass _Base
。
property
对象是 descriptors,描述符仅在 class 或 metaclass 上定义时调用。您不能将它们直接放在实例上; __getattribute__
classes 的实现根本不调用所需的绑定行为。
您需要将 属性 放在 class 上,而不是在每个实例上:
class Foo:
def __init__(self, x):
self._x = x
@property
def x(self): return self._x
@x.setter
def x(self, y): self._x = y
如果你必须有一个只适用于某些情况的 属性,你将不得不改变你的 getter 和 setter 方法来改变行为(比如引发 AttributeError
因为当实例的状态是属性应该 'not exist').
class Bar:
def __init__(self, has_x_attribute=False):
self._has_x_attribute = has_x_attribute
self._x = None
@property
def x(self):
if not self._has_x_attribute:
raise AttributeError('x')
return self._x
@x.setter
def x(self, y):
if not self._has_x_attribute:
raise AttributeError('x')
self._x = y
property
对象仍然存在并被绑定,但当标志设置为 false 时,其行为就好像该属性不存在一样。