Method / Functions - What are the differences?
Bruno Desthuilliers
bruno.42.desthuilliers at websiteburo.invalid
Fri Mar 5 07:15:59 EST 2010
John Posner a écrit :
> On 3/3/2010 6:56 PM, John Posner wrote:
>>
>> ... I was thinking
>> today about "doing a Bruno", and producing similar pieces on:
>>
>> * properties created with the @property decorator
>>
>> * the descriptor protocol
>>
>> I'll try to produce something over the next couple of days.
>>
>
> Starting to think about a writeup on Python properties, I've discovered
> that the official Glossary [1] lacks an entry for "property" -- it's
> missing in both Py2 and Py3!
>
> Here's a somewhat long-winded definition -- comments, please:
>
> ---------------------------------------------
> An attribute, *a*, of an object, *obj*, is said to be implemented as a
> property if the standard ways of accessing the attribute:
>
> * evaluation: print obj.a
> * assignment: obj.a = 42
> * deletion: del obj.a
>
> ... cause methods of a user-defined *property object* to be invoked.
Hmmm... a couple remarks:
1/ "property" is actually the name of a Python builtin type. It's also
pretty much used in general OO litterature for what we name
"attributes". So I think it would be better to avoid confusion between
"property" as the builtin type, "property" as synonym for attribute, and
"property" as the more specific concept of "computed attribute" - which
is what you're describing here.
As far as I'm concerned, I prefer to stick to "computed attribute" for
the generic case, and only use "property" when the computed attribute is
actually implemented using the builtin property type.
2/ depending on how the computed attribute is implemented, the
computation needs not happen on ALL get/set/del access - you can have
non-binding descriptors (that is, not implementing __set__).
Also, the "standard" access also include getattr(), setattr() and
delattr() (might be worth a note).
> The
> attribute
/attribute/user-defined object/ here ?
> is created as a class attribute, not an instance attribute.
> Example:
>
> class Widget:
> # create "color" as class attribute, not within __init__()
> color = <<property-object>>
>
> def __init__(self, ...):
> # do not define "self.color" instance attribute
Yes you can, and it's even actually pretty common:
# example.py
from somewhere import RGBColor
class Foo(object):
def _get_color(self):
return str(self._color)
def _set_color(self, val):
self._color = RGBColor.from_string(val)
color = property(fget=_get_color, fset=_set_color)
def __init__(self, colorvalue):
self.color = colorvalue
> The property object can be created with the built-in function
> property(),
It's actually a type, not a function.
> which in some cases can be coded as a decorator: @property.
> The property object can also be an instance of a class that implements
> the descriptor protocol.
The "property object" IS an instance of a class that implements the
descriptor protocol. The property type is just a "generic" descriptor:
# naive (and incomplete) python implementation of the property type
class property(object):
def __init__(self, fget, fset=None, fdel=None)
self._fget = fget
self._fset = fset
self._fdel = fdel
def __get__(self, instance, cls):
if instance is None:
return self
return self._fget(instance)
def __set__(self, instance, value):
if not self._fset:
raise AttributeError("can't set attribute")
self._fset(instance, value)
def __del__(self):
if not self._fdel:
raise AttributeError("can't delete attribute")
self._fdel(instance)
As far as I'm concerned, I'd "plan" such a paper as:
"""
What's a property ? It's a computed attribute implemented using the
builtin "property" type.
Ok, so far it doesn't help much. So
1/ what's a computed attribute, and
2/ what is the property type ?
1/ your above explanation about what's a computed attribute in general,
then a brief explanation of how computed attributes are implemented in
python -> IOW, the descriptor protocol
2/ my above snippet !-)
"""
I think the way you started explaining computed attributes wrt/
attribute access could be a pretty good way to explain the descriptor
protocol, since the mapping from get/set/del access to __get__, __set__,
and __del__ magic methods is then pretty obvious.
But YMMV of course, so by all mean feel free to discard all or parts of
the above remarks !-)
HTH
More information about the Python-list
mailing list