property decorator?

Ian Kelly ian.g.kelly at gmail.com
Wed Dec 20 22:38:48 EST 2017


On Wed, Dec 20, 2017 at 5:56 PM, Irv Kalb <Irv at furrypants.com> wrote:
> My questions about this are really historical.  From my reading, it looks like using an @property decorator is a reference to an older approach using a built in "property" function.  But here goes:
>
> 1) Why were these decorator names chosen?  These two names @property and @<name>.setter don't seem to be very clear to me.  At a minimum, they don't match.  Wouldn't decorator names like @<name>.getter and @<name>.setter have been better - more explicit?

That wouldn't work because @<name>.getter causes Python to look up the
<name> variable within the class scope and then its getter attribute.
But <name> hasn't been defined yet and won't be until after the getter
has been created.

> 2)  Alternatively, if the getter was going to use the @property decorator, then it would seem complimentary  to have the decorator name for the associated setter function to have the word "property" in its also, something like @propertySetter.

Perhaps this could have been done, but unlike the getter, the setter
is being defined on a property that now already exists. In this case
<name> has to be referenced somewhere within the decorator or else the
setter property will simply replace the getter property, rather than
augment and then replace it.

I suppose what it boils down to is that there's no particular reason
to look up "property" again since the getter already declared that
this is a property.

> 3)  If I create a method with the @property decorator, is there anything else that is implied about the name of the method other than you can now refer to the <objectName>.<name> - which calls the appropriate method?  My guess/understanding is that in my example above, "salary" is considered the property name, which is how you would refer to it outside of the object. Inside the class, you use the property name as the name of both the setter and the getter methods.  Is that the right way to think about it?

No, "salary" is the property name regardless of whether you're
referring to it from inside or outside of the class definition. With
the notable exceptions of super() and double-underscore name mangling,
Python generally doesn't care about *where* an attribute or method
reference is made from.

> Finally, it seems very odd to me that when you use the @property decorator and the @<variableName>.setter, that both of the methods that are decorated need to have the same name (but of course different set of parameters.)  As a teacher, this seems like it would be an extremely difficult concept to get across to students, as this does not work the same way as other Python functions (and methods).  Without a decorator, the second function of the same name overrides an earlier function of the same name, as in this simple example:

Strictly speaking, they don't *need* to have the same name. This works:

class Employee():

    def __init__(self, name, salary):
        self.__name = name
        self.__salary = salary

    @property
    def salary_one(self):
        print('Getting salary of', self.__name, 'which is:', self.__salary)
        return self.__salary

    @salary_one.setter
    def salary_two(self, newSalary):
        print('Setting salary of', self.__name, 'to:', newSalary)
        self.__salary = newSalary


The result would be that Employee has a get-only property named
salary_one since it was never overwritten, and a get-set property
named salary_two that combines the getter from salary_one with a new
setter. If you wanted to, you could then:

    del salary_one

and only salary_two would exist as in the usual case. But this is
mostly just for demonstration of the object model; there's no
practical reason to use different names for each.



More information about the Python-list mailing list