在 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
但我需要在方法内完成它。还有别的办法吗?
谢谢你,
鲁比克
我已经检查过这篇文章,但它并没有解决我的问题: 在方法内使用 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
I want to set a read-only attribute inside a class method.
I have already tried this:
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)))
but it is horrible. Is there another way? What I need to do is setting the property:
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
but I need to do it inside a method. Is there another way?
Thank you,
rubik
P.S. I have already checked this post, but it does not solve my problem:
Using Python property() inside a method
EDIT: I cannot use property
, because I want to set it inside a method. I can use property
only from outside:
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)
And I can't do that because I don't know the property name and I have to set it dynamically. Something like this:
class Foo(object):
def __init__(self, v):
self._set_property_from_inside('v', v)
>>> f = Foo(42)
>>> f.v
42
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为您正在寻找 python 描述符。
在这里,您可以在
__get__
和__set__
方法中执行任何您想要控制访问的操作。如果您在__get__
中调用 obj.get_v 并在__set__
中调用 obj.set_v,这与属性的实际实现非常接近,如上面的链接所示。编辑:已修复。我自己应该更好地阅读该页。引用:
因此,如果您将描述符放入实例的 __dict__ 中,那么当您将该属性设置为新值时,它们就会被覆盖。
I think you're looking for python descriptors.
Here you can do whatever you want to control access in the
__get__
and__set__
methods. If you call obj.get_v in__get__
and obj.set_v in__set__
, this is very close to the actual implementation of a property, as you can see in the above link.Edit: Fixed. I should have read that page better myself. Quoting:
So if you put descriptors in the
__dict__
of the instance, they'll simply get overwritten when you set that attribute to a new value.然后:
Then:
我已经想到了一个更干净的解决方案来实现纯只读属性,如果这就是您想要的。它是 tangentstorm 给出的解决方案的一个变体,但完全不需要
__getattr__
方法。它的工作原理如下:
使只读属性再次读写很容易:
在我第一次尝试编写这个想法时,我使用了 self.__readonly 而不是 self.readonly ,但这会导致实际设置 __readonly 属性时出现问题,因为我需要取消修改“private”属性来检查其是否存在 (
hasattr(self, " _Foo__readonly")
),这是不鼓励的。I've thought of what I think is a cleaner solution for implementing a pure read-only attribute, if that's all you want. It's a variant of the solution tangentstorm gave, but dispenses with the need for a
__getattr__
method altogether.It works like this:
Making a read-only attribute read-write again is easy:
In my first attempt at writing this idea I used
self.__readonly
instead ofself.readonly
, but that leads to a problem with actually setting the__readonly
attribute, since I'd need to do un-munge the "private" attribute to check for its presence (hasattr(self, "_Foo__readonly")
), and this is discouraged.property() 正是这里的解决方案。为什么不应该解决你的问题?
重写 setter 和 getter 方法可以让您准确地实现您想要和需要的功能:对属性的完全控制。
请查看官方文档,例如
http://docs.python.org/library/functions.html #property
以便了解整个故事。
property() is exactly the solution here. Why shouldn't is solve your problem?
Overriding the setter an getter method allows you exactly what you want and need: full control over the property.
Please check with official documentation like
http://docs.python.org/library/functions.html#property
in order to understand the whole story.