About the use of **args

Graham Ashton gashton at cmedltd.com
Wed Dec 10 04:24:54 EST 2003


On Wed, 10 Dec 2003 09:38:55 +0100, Zunbeltz Izaola wrote:

> I'm starting a new proyect and i'm in doubt about diferent interfaces
> for my clases. My clases will have a lot of attributes and i'm want to
> know what aproach could be the best
> 
> 1) Define one SetAttribute/GetAttribute pair of method for each
>    attribute.
> 2) Define one SetAttribute/GetAttribute which argument is a key=value
>    format.

I asked a similar question myself when I started out with Python, and I
got some very good answers that served me well.

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=rVCZ6.1492%24h45.9746%40news.uk.colt.net&rnum=2&prev=/groups%3Fq%3Dgraham%2Bashton%2Battribute%2Bpython%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3DrVCZ6.1492%2524h45.9746%2540news.uk.colt.net%26rnum%3D2

My preferred technique is to just set attributes directly on the object,
like this:

  shoe = Shoe()
  shoe.laced_up = True
  shoe.is_on_foot = True
  shoe.resoled = False

You may think that it's a bit nasty because it breaks encapsulation, etc.,
but Python is designed to let you do stuff quickly and cleanly. You're
not always in a situation where you need to enforce access so
strictly. Using attributes directly is more of a Python idiom (see the
last two posts in the thread I posted earlier).

Since that earlier thread Python has been given a nice way of
customising attribute access; properties. Basically, they let you
define get/set methods that get run when you access/assign to an
attribute. You benefit by getting a cleaner interface to your class, and
you only have to define get/set methods when you actually need them (i.e.
when they have side effects other than getting/setting the attribute).

For example:

  class Shoe:

    def __init__(self):
      self._laced_up = False
      self.is_on_foot = False
      self.resoled = False

    def _set_laced_up(self, boolean):
      self._laced_up = boolean
      if boolean:
        self.is_on_foot = True

    def _get_laced_up(self):
      return self._laced_up

    laced_up = property(_get_laced_up, _set_laced_up)

I've not run that so it may have syntax errors. It should illustrate the
principle though; you can use attributes directly until you want to take
actions when you set them. Then you can make the attribute "private" and
replace it with a property that access the real attribute, and does
whatever else you want to do when it's accessed.

Hope that makes sense.

-- Graham




More information about the Python-list mailing list