在Python方法中设置属性 [英] Setting a property inside a Python method

查看:138
本文介绍了在Python方法中设置属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我想在类方法中设置只读属性。

我已经尝试过:

  class Foo(object):
def __init __(self,v):
self._set('_ v',v)
$ b b 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 = v

@ property
def v(self):
return self._v

>> ;> f = Foo(42)
>>>> f.v
42
>>>> fv = 41
AttributeError:不能设置属性##这是我想要的:只读属性


b $ b

但我需要在一个方法里面做。还有别的办法吗?



谢谢

rubik



我已经检查过这个帖子,但它不能解决我的问题:
使用



编辑:我不能使用属性以将其设置在方法内部。我只能从外部使用属性

 
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)
>>>> fv
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)和attr in self.readonly:
raise AttributeError(只读属性:%s%(attr,))
对象.__ 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
回溯(最近最后一次调用):
在< module>中的文件< stdin&
文件ro.py,第13行,在__setattr__
raise AttributeError(只读属性:%s%(名称,))
AttributeError:只读属性:y

再读一次只读属性很容易:

  def unset_readonly(self,attr):
self.readonly.remove(attr)
p>

在我第一次尝试写这个想法时,我使用了 self .__ readonly 而不是 self.readonly ,但是这导致了实际设置 __ readonly 属性的问题,因为我需要将private属性检查它的存在( hasattr(self,_Foo__readonly)),这是不鼓励的。



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

解决方案

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.

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)

It works like this:

>>> 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

Making a read-only attribute read-write again is easy:

    def unset_readonly(self, attr):
        self.readonly.remove(attr)

In my first attempt at writing this idea I used self.__readonly instead of self.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.

这篇关于在Python方法中设置属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆