[Tutor] subclass question

Rich Lovely roadierich at googlemail.com
Sun Dec 20 10:39:25 CET 2009


2009/12/20 David Perlman <dperlman at wisc.edu>:
> If I make a subclass of a built-in class, like this:
>
> class mylist(list):
>    def __init__(self):
>        list.__init__(self)
>
> Then it is valid for me to do this:
>
>>>> x=mylist()
>>>> x.hello=3
>>>>
>
> But I can't do this:
>
>>>> y=list()
>>>> y.hello=3
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
> AttributeError: 'list' object has no attribute 'hello'
>>>>
>
> What is it that is special about built-in classes that prevents you from
> adding methods or, uh, whatever the generic term is for sub-variables?  Is
> there a way to make your own classes restricted like that?
>
> OK thanks!
>
>
> --
> -dave----------------------------------------------------------------
> Unfortunately, as soon as they graduate, our people return
> to a world driven by a tool that is the antithesis of thinking:
> PowerPoint. Make no mistake, PowerPoint is not a neutral tool —
> it is actively hostile to thoughtful decision-making. It has
> fundamentally changed our culture by altering the expectations
> of who makes decisions, what decisions they make and how
> they make them.  -Colonel T. X. Hammes, USMC
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>

You can use the __slots__ attribute to get the same behaviour:
>>> class Demo(object):
...     __slots__ = []
...
>>> d = Demo()
>>> d.a=1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Demo' object has no attribute 'a'

But beware:  You need to add every attribute you want your class to
have to __slots__, if they're not defined on the class (i.e. instance
variables, defined within methods):

>>> class Demo(object):
...    def __init__(self):
...        self.a = 1
...    __slots__ = []
...
>>> d = Demo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
AttributeError: 'Demo' object has no attribute 'a'
>>> class Demo(object):
...    def __init__(self):
...        self.a = 1
...    __slots__ = ['a']
...
>>> d = Demo()
>>> d.a
1

This will need updating every time you add a new instance variable to
a class, but it does help detect typos.

There is also the option of using __getattr__, __setattr__ and so on,
but that's a little more complicated.

I will however say, that the original behaviour is entirely
intentional.  Python was designed to be a language used by consenting
adults who should know better than doing things that are likely to
break stuff.  For instance, there is nothing to stop you from
overwriting any of the builtin functions or types.

See http://docs.python.org/reference/datamodel.html#slots for some of
the other side effects.

-- 
Rich "Roadie Rich" Lovely

There are 10 types of people in the world: those who know binary,
those who do not, and those who are off by one.


More information about the Tutor mailing list