Class methods read-only by default?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Apr 2 15:56:01 CEST 2009


On Thu, 02 Apr 2009 06:07:20 -0700, Emanuele D'Arrigo wrote:

> Hi Everybody!
> 
> I just tried this:
> 
>>>> class C(object):
> ...    def method(self):
> ...        pass
> ...
>>>> c = C()
>>>> delattr(c, "method")
> 
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: 'C' object attribute 'method' is read-only
> 
> How come? Who told the class to make the method read-only? I didn't!

Nobody told the class to make the method read-only, because it isn't. You 
are trying to delete an *instance* attribute (one that lives inside the 
instance dictionary) but the method is a *class* attribute (it lives 
inside the class dictionary).


>>> class C(object):
...     def method(self): pass
...
>>> c = C()
>>> C.__dict__.keys()  # class attributes
['__dict__', '__module__', '__weakref__', 'method', '__doc__']
>>> c.__dict__.keys()  # instance attributes
[]

To remove the method, this will work:

delattr(C, 'method')  # call on the class


But beware, if method is defined in a superclass of C, then that won't 
work either.

This is a little confusing, it is a definite Gotcha, because getattr 
succeeds. But notice:

>>> getattr(c, 'method')
<bound method C.method of <__main__.C object at 0x82ec14c>>

See how it tells you that c.method is actually C.method?


-- 
Steven



More information about the Python-list mailing list