Understanding the pythonic way: why a.x = 1 is better than a.setX(1) ?

Carl Banks pavlovevidence at gmail.com
Thu Sep 4 19:07:04 EDT 2008


On Sep 4, 3:15 pm, Ivan Illarionov <ivan.illario... at gmail.com> wrote:
> On 4 ÓÅÎÔ, 22:59, Carl Banks <pavlovevide... at gmail.com> wrote:
> > You can write code to guard against this if you want:
>
> > class A:
> >   legal = set(["x"])
> >   def __setattr__(self,attr,val):
> >     if attr not in self.legal:
> >       raise AttributeError("A object has no attribute '%s'" % attr)
> >     self.__dict__[attr] = val
> >   def __init__(self,x):
> >     self.y = x
>
> > I suspect most people who go into Python doing something like this
> > soon abandon it when they see how rarely it actually catches anything.
>
> > Carl Banks
>
> '__slots__' is better:
> class A(object):
>     __slots__ = set(["x"])
>     def __init__(self, x):
>         self.y = x
>
> this will do the same, only faster>>> A(1)
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 4, in __init__
> AttributeError: 'A' object has no attribute 'y'


However, if you subclass your version of A that uses __slots__, the
subclass will once again allow all attribute access, whereas if you
subclass my version of A that uses __getattr__, it will still be
restricted to the allowed symbols (unless you were to override the
list of symbols, which you probably would).

The latter behavior is less surprising and less dangerous, which
(besides the questionable usage) is the main reason using __slots__ is
not recommended for this purpose.

(Having said that, I do admit to using __slots__ for this purpose
once.  But, the confusing aspects of __slots__ were managed by a
metaclass and hidden from the user.)


Carl Banks



More information about the Python-list mailing list