在Python方法中设置属性
问题内容:
我想在类方法中设置一个只读属性。
我已经尝试过了:
class Foo(object):
def __init__(self, v):
self._set('_v', v)
def _set(self, attr, v):
setattr(self, attr, v)
setattr(Foo, attr[1:], property(lambda self: getattr(self, attr)))
但这太可怕了。还有另一种方法吗?我需要做的是设置属性:
class Foo(object):
def __init__(self, v):
self._v = v
@ property
def v(self):
return self._v
>>> f = Foo(42)
>>> f.v
42
>>> f.v = 41
AttributeError: can't set attribute ## This is what I want: a read-only attribute
但是我需要在一个方法中做 还有另一种方法吗?
谢谢
rubik
PS我已经检查了这篇文章,但不能解决我的问题: 在方法中使用Python
property()
编辑:我不能使用property
,因为我想在一个方法内设置它。我property
只能从外面使用:
class Foo(object):
def __init__(self, v):
self._v = v
@ property
def v(self):
return self._v
## ...OR
def getv(self):
return self._v
v = property(getv)
而且我不能这样做,因为我不知道属性名称,因此必须动态设置它。像这样:
class Foo(object):
def __init__(self, v):
self._set_property_from_inside('v', v)
>>> f = Foo(42)
>>> f.v
42
问题答案:
我想过的是,我想这是一种用于实现纯只读属性的更干净的解决方案。它是tangentstorm提供的解决方案的一种变体,但__getattr__
完全不需要使用该方法。
class Foo(object):
def __init__(self):
self.readonly = set()
def set_readonly(self, attr, value):
setattr(self, attr, value)
self.readonly.add(attr)
def __setattr__(self, attr, value):
if hasattr(self, "readonly") and attr in self.readonly:
raise AttributeError("Read only attribute: %s" % (attr,))
object.__setattr__(self, attr, value)
它是这样的:
>>> f = Foo()
>>> f.x = 5
>>> f.set_readonly("y", 9)
>>> f.x, f.y
(5, 9)
>>> f.x = 7
>>> f.y = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ro.py", line 13, in __setattr__
raise AttributeError("Read only attribute: %s" % (name,))
AttributeError: Read only attribute: y
使只读属性再次可读写很容易:
def unset_readonly(self, attr):
self.readonly.remove(attr)
在我第一次尝试编写此想法时,我使用self.__readonly
而不是self.readonly
,但这会导致实际上设置__readonly
属性存在问题,因为我需要取消“
private”属性的检查,以检查其存在(hasattr(self, "_Foo__readonly")
),并且不鼓励。