Concrete classes -- stylistic question

Steve Holden sholden at holdenweb.com
Thu Oct 10 19:43:01 CEST 2002


I think you're being a bit too complex here. A long time ago I remember Alex
Martelli posting someting along the follwoing lines, which still works well
today. Forgive me if it doesn't meet some part of your requirements.

>>> class Record(object):
...   def __init__(self, **args):
...     self.__dict__.update(args)
...
>>> pt = Record(x=1, y=2)
>>> pt.x
1
>>> pt.z
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'Record' object has no attribute 'z'
>>>

Any good?

regards
-----------------------------------------------------------------------
Steve Holden                                  http://www.holdenweb.com/
Python Web Programming                 http://pydish.holdenweb.com/pwp/
Previous .sig file retired to                    www.homeforoldsigs.com
-----------------------------------------------------------------------
"Andrew Koenig" <ark at research.att.com> wrote in message
news:yu99r8ey47cr.fsf at europa.research.att.com...
> On a few occasions I've wanted to define ``concrete classes'' --
> classes that are so simple that their structure is their interface.
> For example, I might want a little class to hold (x, y) pairs.
>
> Of course, I can use a tuple, but then I have to remember the meaning
> of each element.  Moreover, if I want to have (x, y) pairs and (r, theta)
> pairs, I don't have an easy way of checking which one is which in case
> I use the wrong one by accident.
>
> Of course, I could define little classes like this:
>
>         class xy(object):
>                 def __init__(self, x, y):
>                         self.x, self.y = x, y
>
>         class rtheta(object):
>                 def __init__(self, r, theta):
>                         self.r, self.theta = r, theta
>
> Then, if I execute
>
>         foo = xy(3, 4)
>         foo.r
>
> I will learn quickly that I used the wrong class.
>
> If I want a number of such classes, it's something of a pain to define
> each one separately.  So I came up with an idea:
>
>     class Record(object):
>         def __init__(self, **args):
>             for i in args:
>                 setattr(self, i, args[i])
>         def __repr__(self):
>             names = filter(
>                 lambda x: not (len(x) >= 4 and x[:2] == x[-2:] == "__"),
>                 dir(self))
>             names.sort()
>             return "Record(" + ", ".join(
>                       map(lambda x: x + '=' + `getattr(self, x)`, names))
+ ")"
>
> Here's an example of how one might use it:
>
>     >>> foo = Record(x=3, y=4)
>     >>> foo
>     Record(x=3, y=4)
>     >>> foo.x
>     3
>     >>> foo.y
>     4
>     >>> foo.r
>     AttributeError: 'Record' object has no attribute 'r'
>
> My questions:
>
>         1) Am I reinventing the wheel here?  If so, where is the original?
>
>         2) Is this approach Pythonic?  If not, why not, and what would you
>            recommend as an alternative?
>
> --
> Andrew Koenig, ark at research.att.com, http://www.research.att.com/info/ark






More information about the Python-list mailing list