Re: Class methods read-only by default?

2009-04-03 Thread Emanuele D'Arrigo
Thank you both, Steven and Andrew, for the insightful explanation. I
shall keep it in mind when thinking about classes methods and
instances. Thank you again.

Manu
--
http://mail.python.org/mailman/listinfo/python-list


Re: Class methods read-only by default?

2009-04-03 Thread Piet van Oostrum
 Emanuele D'Arrigo man...@gmail.com (ED) wrote:

ED Hi Everybody!
ED I just tried this:

 class C(object):
ED ...def method(self):
ED ...pass
ED ...
 c = C()
 delattr(c, method)

ED Traceback (most recent call last):
ED   File stdin, line 1, in module
ED AttributeError: 'C' object attribute 'method' is read-only

ED How come? Who told the class to make the method read-only? I didn't!

Methods in a class are done with the descriptor protocol. All access to
the method through an instance is executed via the descriptor. The
delete calls the __delete__ method of the descriptor which isn't
implemented for functions. See
http://docs.python.org/reference/datamodel.html?highlight=descriptor#implementing-descriptors
(Actually, IIRC, the function object is its own descriptor)

 class C(object):
...   def method(self):
... pass
... 
 c=C()
 C.__dict__['method']
function method at 0xd2330
 C.__dict__['method'].__get__
method-wrapper '__get__' of function object at 0xd2330
 C.__dict__['method'].__delete__
Traceback (most recent call last):
  File stdin, line 1, in module
AttributeError: 'function' object has no attribute '__delete__'
 

-- 
Piet van Oostrum p...@cs.uu.nl
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
--
http://mail.python.org/mailman/listinfo/python-list


Re: Class methods read-only by default?

2009-04-02 Thread andrew cooke
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!

i'm just guessing, but i suspect this is because of how it's implemented. 
class methods don't exist in the instance.  instead, they exist in the
class (which is itself an object, hence metaclasses etc), and the
instance forwards them to the class for evaluation (if the term vtable
makes any sense to you then the vtable for class methods is owned by the
class, not the instance).

so you may be able to delete the method from the class, but then it will
affect all instances.  you can't delete it from one instance because it's
not in that instance.

as i said, just a guess, based on vague ideas about how python works.

andrew


--
http://mail.python.org/mailman/listinfo/python-list


Re: Class methods read-only by default?

2009-04-02 Thread Steven D'Aprano
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
--
http://mail.python.org/mailman/listinfo/python-list