Python class @property: use setter but evade getter?

半腔热情 提交于 2019-11-28 03:54:41

Don't use a property in this case. A property object is a data descriptor, which means that any access to instance.var will invoke that descriptor and Python will never look for an attribute on the instance itself.

You have two options: use the .__setattr__() hook or build a descriptor that only implements .__set__.

Using the .__setattr__() hook

class MyClass(object):
    var = 'foo'

    def __setattr__(self, name, value):
        if name == 'var':
            print "Setting var!"
            # do something with `value` here, like you would in a
            # setter.
            value = 'Set to ' + value
        super(MyClass, self).__setattr__(name, value)

Now normal attribute lookups are used when reading .var but when assigning to .var the __setattr__ method is invoked instead, letting you intercept value and adjust it as needed.

Demo:

>>> mc = MyClass()
>>> mc.var
'foo'
>>> mc.var = 'bar'
Setting var!
>>> mc.var
'Set to bar'

A setter descriptor

A setter descriptor would only intercept variable assignment:

class SetterProperty(object):
    def __init__(self, func, doc=None):
        self.func = func
        self.__doc__ = doc if doc is not None else func.__doc__
    def __set__(self, obj, value):
        return self.func(obj, value)

class Foo(object):
    @SetterProperty
    def var(self, value):
        print 'Setting var!'
        self.__dict__['var'] = value

Note how we need to assign to the instance .__dict__ attribute to prevent invoking the setter again.

Demo:

>>> f = Foo()
>>> f.var = 'spam'
Setting var!
>>> f.var = 'ham'
Setting var!
>>> f.var
'ham'
>>> f.var = 'biggles'
Setting var!
>>> f.var
'biggles'

property python docs: https://docs.python.org/2/howto/descriptor.html#properties

class MyClass(object):
    def __init__(self):
        self._var = None

    # only setter
    def var(self, newValue):
        self._var = newValue

    var = property(None, var)


c = MyClass()
c.var = 3
print ('ok')
print (c.var)

output:

ok
Traceback (most recent call last):
  File "Untitled.py", line 15, in <module>
    print c.var
AttributeError: unreadable attribute
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!