repr(x) != x.__repr__()
This phenomenon is not really specific to repr(). It occurs with new-style classes when methods are assigned. Example: class A(object): def __repr__(self): return 'abc'
a = A() a.__repr__ = lambda: 'abc' repr(a) 'abc' a.__repr__() '123'
Whenever the method is accessed by Python code it sees the assigned method in the object's __dict__. Builtins like repr(), iter() etc, see the original class method. With classic objects both Python and C code see the assigned function. This is bug #515336 on sourceforge. Is anyone aware of any other cases where C code and Python code don't see objects the same way? Oren
This phenomenon is not really specific to repr(). It occurs with new-style classes when methods are assigned.
Example:
class A(object): def __repr__(self): return 'abc'
a = A() a.__repr__ = lambda: 'abc'
You meant '123' there. :-)
repr(a) 'abc' a.__repr__() '123'
Whenever the method is accessed by Python code it sees the assigned method in the object's __dict__. Builtins like repr(), iter() etc, see the original class method. With classic objects both Python and C code see the assigned function. This is bug #515336 on sourceforge.
I'm probably going to reject this bug as "won't fix". I specifically put code in the new classes to create this behavior. It's partly a performance hack: many operations become much slower if they have to check the instance __dict__ first. But I also believe it's poor style to override a system operation on the instance rather than on the class. If you want to be able to override behavior per instance, use this: class A(object): def __repr__(self): return self.repr() def repr(self): return 'abc' a = A() a.repr = lambda: '123' assert repr(a) == a.__repr__() == '123'
Is anyone aware of any other cases where C code and Python code don't see objects the same way?
Yes, a+b is not the same as a.__add__(b). a[i:j] is not the same as a.__getslice__(i, j). --Guido van Rossum (home page: http://www.python.org/~guido/)
On Thu, Mar 28, 2002 at 10:28:12AM -0500, Guido van Rossum wrote:
I'm probably going to reject this bug as "won't fix". I specifically put code in the new classes to create this behavior. It's partly a performance hack: many operations become much slower if they have to check the instance __dict__ first. But I also believe it's poor
If this is by design it's ok. I suspected it might be an accidental result of the different internal structure of new style classes.
check the instance __dict__ first. But I also believe it's poor style to override a system operation on the instance rather than on the class.
And if it's not a system operation? Is method assignment in general considered poor style? Something as vile and unspeakable as changing an object's __class__ at runtime? ;-) Oren
On Thu, Mar 28, 2002 at 10:28:12AM -0500, Guido van Rossum wrote:
I'm probably going to reject this bug as "won't fix". I specifically put code in the new classes to create this behavior. It's partly a performance hack: many operations become much slower if they have to check the instance __dict__ first. But I also believe it's poor
If this is by design it's ok. I suspected it might be an accidental result of the different internal structure of new style classes.
Yes, I thought about it long and hard and decided that it should be a feature.
check the instance __dict__ first. But I also believe it's poor style to override a system operation on the instance rather than on the class.
And if it's not a system operation? Is method assignment in general considered poor style?
That's up to the application.
Something as vile and unspeakable as changing an object's __class__ at runtime? ;-)
I don't know what you're talking about. :-) --Guido van Rossum (home page: http://www.python.org/~guido/)
[Oren Tirosh]
This phenomenon is not really specific to repr(). It occurs with new-style classes when methods are assigned.
Example:
class A(object): def __repr__(self): return 'abc'
a = A() a.__repr__ = lambda: 'abc' repr(a) 'abc' a.__repr__() '123'
You've got a typo in there. Here is the fixed version:
class A(object): ... def __repr__(self): ... return 'abc' ... a = A() a.__repr__ = lambda: '123' repr(a) 'abc' a.__repr__() '123'
Of course, the odd behavior is still there. --- Patrick K. O'Brien Orbtech
participants (3)
-
Guido van Rossum -
Oren Tirosh -
Patrick K. O'Brien