[ python-Bugs-1066490 ] special methods become static
SourceForge.net
noreply at sourceforge.net
Wed Dec 22 20:00:46 CET 2004
Bugs item #1066490, was opened at 2004-11-14 23:46
Message generated for change (Comment added) made by kquick
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1066490&group_id=5470
Category: Type/class unification
Group: Python 2.3
>Status: Open
Resolution: Invalid
Priority: 5
Submitted By: Kevin Quick (kquick)
Assigned to: Michael Hudson (mwh)
Summary: special methods become static
Initial Comment:
This *may* be a duplicate of 729913, but there's either additional
info here, or this is actually different.
The issue is that any special method (e.g. __call__, __str__, etc.)
defined for a new-style (i.e. object-based) class seems to be static
(i.e. unchangeable) with some special lookup applied for that method,
but this doesn't seem to be the case for regular methods.
class A:
def foo(self): return 1
def __call__(self): return 2
def bar(self): return 3
def adjust(self):
self.foo = self.bar
self.__call__ = self.bar
a = A()
print a.foo(), a()
a.adjust()
print a.foo(), a()
Will print:
1 2
3 3
But if the A is turned into a new-style class by changing the
first line:
class A(object):
then the printed results are:
1 2
3 2
To the best of my understanding of the migration from classic classes
to new-style classes (and metaclassing), this shouldn't occur. I have
also tried various name munging for the special method (e.g. setting
_B__call__, using setattr, etc.), but I haven't found the special trick
yet.
The attached script shows the example in more detail.
----------------------------------------------------------------------
>Comment By: Kevin Quick (kquick)
Date: 2004-12-22 12:00
Message:
Logged In: YES
user_id=6133
Thanks for the clarifcation. However IMHO it is wrong to have different
behavior for different methods.
To wit, if I defined a method, it is a bound method, and ergo a "self" initial
argument is automatically supplied. However, a __repr__, even though I
define it, acts as an unbound method, with the self argument having a default
of the current instance but overrideable if an argument is supplied on the call.
This means that the argument evaluation/passing is different for these types
of builtins as opposed to other methods, both of which I have defined myself.
This just doesn't seem right to me, which is why I'm re-opening this bug
report... sorry to be annoying, but this definitely seems inconsistent and a
better explanation.
My current workaround is to do the following:
class foo:
def __str__(self):
return my_str()
def my_str(self):
return 'something'
So that I can do "foo.my_str = lambda self: return 'something else'".
When what I should be able to do is:
class foo:
def __str__(self):
return 'something'
...
foo.__str__ = lambda self: return 'something else'
----------------------------------------------------------------------
Comment By: Michael Hudson (mwh)
Date: 2004-11-16 01:22
Message:
Logged In: YES
user_id=6656
Oh, sorry, I think I got that a bit wrong. The issue is more with
bound/unbound methods -- given
class O(object):
def __repr__(self):
...
should O.__repr__ be a bound method (O is an instance of type)
or an unbound method so O.__repr__(O()) does what you expect?
Python chooses the latter, but this means that you can't implement
the builtin function repr as
def repr(o):
return o.__repr__()
Hope this helps, a little at least.
----------------------------------------------------------------------
Comment By: Kevin Quick (kquick)
Date: 2004-11-15 07:29
Message:
Logged In: YES
user_id=6133
OK, I didn't find anything documenting this change anywhere (obviously).
I read Guido's description of new-classes (www.python.org/2.2/descrintro.py)
and the various documentation, but either I overlooked it therein or it's talked
about somewhere else.
I'm curious as to why special methods are treated specially in regards to this
lookup. Specifically for your example, why wouldn't you just use the
__repr__ attribute of o if it exists, instead of o's class, just like it does for
non-special methods? Can you briefly explain this or provide me with a
reference?
Leaving this closed is OK with me since it's apparently known and expected...
I'd just like to understand it a bit better. Sorry for the bandwidth, and Thanks!
----------------------------------------------------------------------
Comment By: Michael Hudson (mwh)
Date: 2004-11-15 00:16
Message:
Logged In: YES
user_id=6656
The change you are observing is that special methods are now
only looked up on the *class* of the object concerned. This, or
something like this is actually unavoidable -- in
>>> repr(o)
what do you do if both o and the type of o define a __repr__
method?
There are articles on new-style classes out there that should
explain this in more depth. It probably could/should be
documented better in the core -- there are bugs open to that
effect already.
Closing.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1066490&group_id=5470
More information about the Python-bugs-list
mailing list