質問

Since Python strives for there to be one right way, I'm wondering what the purpose of property.getter is. In this example WhyMe defines a getter but Other doesn't so I'm wondering what the point of property.getter is over just using property.

class WhyMe(object):
    def __init__(self):
        self._val = 44

    @property
    def val(self):
        print 'I am not called'
        return self._val

    @val.getter # What advantage do I bring?
    def val(self):
        print 'getter called'
        return self._val

class Other(object):
    def __init__(self):
        self._val = 44

    @property
    def val(self):
        print 'I AM called'
        return self._val

And using them:

>>> why = WhyMe()
>>> why.val
getter called
44
>>> other = Other()
>>> other.val
I AM called
44

I'm no stranger to properties, I'm just wondering if there is some advantage to making a getter or if was just put there for symmetry?

役に立ちましたか?

解決

@property let's you define a whole new property, by defining a getter for that property. The @original.getter syntax lets you override just the existing getter. There are also .setter and .deleter decorators, to the other two methods available to a property.

Imagine you subclassing a custom class that is using a property, with both a getter and a setter defined. If you only wanted to override the getter of that property but leaving the setter in place (or the deleter), using @BaseClass.original.getter lets you do that:

>>> class Foo(object):
...     @property
...     def spam(self):
...         print 'Foo.spam called'
...         return 'spam'
...     @spam.setter
...     def spam(self, value):
...         print 'Foo.spam.setter called'
...     @property
...     def ham(self):
...         print 'Foo.ham called'
...         return 'ham'
...     @ham.setter
...     def ham(self, value):
...         print 'Foo.ham.setter called'
... 
>>> class Bar(Foo):
...     @Foo.spam.getter
...     def spam(self):
...         print 'Bar.spam override'
...         return 'eggs and spam'
...     @property
...     def ham(self):
...         print 'Bar.ham override'
...         return 'eggs and ham'
... 
>>> Bar().spam
Bar.spam override
'eggs and spam'
>>> Bar().spam = 'foo'
Foo.spam.setter called
>>> Bar().ham
Bar.ham override
'eggs and ham'
>>> Bar().ham = 'foo'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

Note that I only replaced the spam getter, while it's setter was preserved. The Bar.ham setter does not exist, I replaced the Foo.ham property wholesale.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top