On Tue, Nov 4, 2014 at 4:52 PM, Roberto MartÃnez <robertomartin...@gmail.com> wrote: > Hi folks, > > I am trying to replace dinamically the __call__ method of an object using > setattr. > Example: > > $ cat testcall.py > class A: > def __init__(self): > setattr(self, '__call__', self.newcall) > > def __call__(self): > print("OLD") > > def newcall(self): > print("NEW") > > a=A() > a() > > I expect to get "NEW" instead of "OLD", but in Python 3.4 I get "OLD". > > $ python2.7 testcall.py > NEW > $ python3.4 testcall.py > OLD > > I have a few questions: > > - Is this an expected behavior? > - Is possible to replace __call__ dinamically in Python 3? How?
For new-style classes, special methods like __call__ are looked up directly on the class, not on the object itself. If you want to change the result of doing a(), then you need to reassign A.__call__, not a.__call__. In python 3, all classes are new-style classes. In python 2, only classes that inherit from 'object' are new-style classes. (If you replace 'class A:' with 'class A(object):' then you'll see the same behaviour on both py2 and py3.) Easy workaround: def __call__(self, *args, **kwargs): return self._my_call(*args, **kwargs) Now you can assign a._my_call to be whatever you want. -n -- Nathaniel J. Smith Postdoctoral researcher - Informatics - University of Edinburgh http://vorpus.org _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com