Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] - نسخه متنی

David Ascher, Alex Martelli, Anna Ravenscroft

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Recipe 6.8. Avoiding Boilerplate Accessors for Properties


Credit: Yakov Markovitch


Problem


Your classes use some
property instances where either the getter or the
setter is just boilerplate code to fetch or set an instance
attribute. You would prefer to just specify the attribute name,
instead of writing boilerplate code.


Solution


You need a factory function that catches the cases in which either
the getter or the setter argument is a string, and wraps the
appropriate argument into a function, then delegates the rest of the
work to Python's built-in
property:

def xproperty(fget, fset, fdel=None, doc=None):
if isinstance(fget, str):
attr_name = fget
def fget(obj): return getattr(obj, attr_name)
elif isinstance(fset, str):
attr_name = fset
def fset(obj, val): setattr(obj, attr_name, val)
else:
raise TypeError, 'either fget or fset must be a str'
return property(fget, fset, fdel, doc)


Discussion


Python's built-in property is
very useful, but it presents one minor annoyance (it may be easier to
see as an annoyance for programmers with experience in Delphi). It
often happens that you want to have both a setter and a
"getter", but only one of them
actually needs to execute any significant code; the other one simply
needs to read or write an instance attribute. In that case,
property still requires two functions as its
arguments. One of the functions will then be just
"boilerplate code" (i.e.,
repetitious plumbing code that is boring, and often voluminous, and
thus a likely home for
bugs).

For example, consider:

class Lower(object):
def _ _init_ _(self, s=''):
self.s = s
def _getS(self):
return self._s
def _setS(self, s):
self._s = s.lower( )
s = property(_getS, _setS)

Method _getS is just
boilerplate, yet you have to code it because you need to pass it to
property. Using this recipe, you can make your
code a little bit simpler, without changing the
code's meaning:

class Lower(object):
def _ _init_ _(self, s=''):
self.s = s
def _setS(self, s):
self._s = s.lower( )
s = xproperty('_s', _setS)

The simplification doesn't look like much in one
small example, but, applied widely all over your code, it can in fact
help quite a bit.

The
implementation of factory function xproperty in this
recipe's Solution is rather rigidly coded: it
requires you to pass both fget and
fset, and exactly one of them must be a string. No
use case requires that both be strings; when neither is a string, or
when you want to have just one of the two accessors, you can (and
should) use the built-in property directly. It is
better, therefore, to have xproperty check that it
is being used accurately, considering that such checks remove no
useful functionality and impose no substantial performance penalty
either.


See Also


Library Reference and Python in a
Nutshell
documentation on the built-in
property.


/ 394