Re: changing __call__ on demand
Stefan Behnel wrote: Thanks for the quick answer. I didn't know they were class-level methods. Too bad. Guess I'll stick with indirection then. Here is one way of doing that indirection I just thought of--have the class __call__ attribute call on the instance __call__ attribute: class MyClass(object): ... def __init__(self, func): ... self.__call__ = func ... def __call__(self, *args, **keywds): ... return self.__call__(*args, **keywds) ... def f1(): return foo ... def f2(x, y): return x+y ... MyClass(f1)() 'foo' MyClass(f2)(30, 12) 42 I still can't figure out whether this is elegant, or opaque and to be avoided. wink -- Michael Hoffman -- http://mail.python.org/mailman/listinfo/python-list
Re: changing __call__ on demand
Stefan Behnel wrote: Hi! This somewhat puzzles me: Python 2.4 (#1, Feb 3 2005, 16:47:05) [GCC 3.3.4 (pre 3.3.5 20040809)] on linux2 Type help, copyright, credits or license for more information. . class test(object): ... def __init__(self): ... self.__call__ = self.__call1 ... def __call1(self): ... print 1 ... def __call__(self): ... print 2 ... . t = test() . t() 2 If I take out the __call__ method completely and only set it in __init__, I get a TypeError saying that test is not callable. Note that it works just fine if you don't use a new-style class: class Test: ... def __init__(self): ... self.__call__ = self.foobar ... def foobar(self, *args, **kwargs): ... print Called with:, args, kwargs ... t = Test() t() Called with: () {} t(3, 4) Called with: (3, 4) {} t(42, x=0) Called with: (42,) {'x': 0} -- Hans Nowak http://zephyrfalcon.org/ -- http://mail.python.org/mailman/listinfo/python-list
changing __call__ on demand
Hi! This somewhat puzzles me: Python 2.4 (#1, Feb 3 2005, 16:47:05) [GCC 3.3.4 (pre 3.3.5 20040809)] on linux2 Type help, copyright, credits or license for more information. . class test(object): ... def __init__(self): ... self.__call__ = self.__call1 ... def __call1(self): ... print 1 ... def __call__(self): ... print 2 ... . t = test() . t() 2 If I take out the __call__ method completely and only set it in __init__, I get a TypeError saying that test is not callable. I want to use this in order to provide different implementations based on the object configuration. Calculating the right function to call is non-trivial and calls are frequent, so I want to change __call__ in order to run the right function directly. I know, I could use another level of indirection: def __call__(self): self.the_right_method() and then set the_right_method accordingly, but I find that somewhat sub-optimal. Is there a way to change __call__ after class creation? Stefan -- http://mail.python.org/mailman/listinfo/python-list
Re: changing __call__ on demand
I tried this: class test(object): ... def __call1(self): ... print 1 ... __call__ = __call1 ... t = test() t() 1 Is that what you were looking for? -- Alan McIntyre ESRG LLC http://www.esrgtech.com Stefan Behnel wrote: Hi! This somewhat puzzles me: Python 2.4 (#1, Feb 3 2005, 16:47:05) [GCC 3.3.4 (pre 3.3.5 20040809)] on linux2 Type help, copyright, credits or license for more information. . class test(object): ... def __init__(self): ... self.__call__ = self.__call1 ... def __call1(self): ... print 1 ... def __call__(self): ... print 2 ... . t = test() . t() 2 If I take out the __call__ method completely and only set it in __init__, I get a TypeError saying that test is not callable. I want to use this in order to provide different implementations based on the object configuration. Calculating the right function to call is non-trivial and calls are frequent, so I want to change __call__ in order to run the right function directly. I know, I could use another level of indirection: def __call__(self): self.the_right_method() and then set the_right_method accordingly, but I find that somewhat sub-optimal. Is there a way to change __call__ after class creation? Stefan -- http://mail.python.org/mailman/listinfo/python-list
Re: changing __call__ on demand
Stefan Behnel wrote: Is there a way to change __call__ after class creation? __call__, like __getitem__, and __getattr__ is called on the class object, not the instance object. So, no, not as far as I am aware, without using metaclass trickery. The simplest option IMO is to use another level of indirection as you suggest. -- Michael Hoffman -- http://mail.python.org/mailman/listinfo/python-list
Re: changing __call__ on demand
Alan McIntyre wrote: class test(object): ...def __call1(self): ...print 1 ...__call__ = __call1 Is that what you were looking for? That still only allows him to have one call function per class. -- Michael Hoffman -- http://mail.python.org/mailman/listinfo/python-list
Re: changing __call__ on demand
Michael Hoffman schrieb: __call__, like __getitem__, and __getattr__ is called on the class object, not the instance object. So, no, not as far as I am aware, without using metaclass trickery. The simplest option IMO is to use another level of indirection as you suggest. Thanks for the quick answer. I didn't know they were class-level methods. Too bad. Guess I'll stick with indirection then. Stefan -- http://mail.python.org/mailman/listinfo/python-list
Re: changing __call__ on demand
Stefan Behnel wrote: Is there a way to change __call__ after class creation? Check out this thread on the topic: http://mail.python.org/pipermail/python-list/2004-January/203142.html Basically, the answer is no -- at least not on a per-instance basis. You can try something like: py class Test(object): ... def __new__(cls): ... cls.__call__ = cls.call1 ... return object.__new__(cls) ... def call1(self): ... print 'call1' ... def __call__(self): ... print '__call__' ... py Test()() call1 But then the call method is changed for all instances: py class Test(object): ... instances = 0 ... def __new__(cls): ... if cls.instances == 1: ... print setting __call__ ... cls.__call__ = cls.call1 ... cls.instances += 1 ... return object.__new__(cls) ... def call1(self): ... print 'call1' ... def __call__(self): ... print '__call__' ... py t1 = Test() py t1() __call__ py t2 = Test() setting __call__ py t2() call1 py t1() call1 Steve -- http://mail.python.org/mailman/listinfo/python-list
Re: changing __call__ on demand
Stefan Behnel wrote: Hi! This somewhat puzzles me: Python 2.4 (#1, Feb 3 2005, 16:47:05) [GCC 3.3.4 (pre 3.3.5 20040809)] on linux2 Type help, copyright, credits or license for more information. . class test(object): ... def __init__(self): ... self.__call__ = self.__call1 ... def __call1(self): ... print 1 ... def __call__(self): ... print 2 ... . t = test() . t() 2 It works the way you want if test is an old-style class: class test: ... def __init__(self): ...self.__call__ = self.__call1 ... def __call1(self): ...print 1 ... def __call__(self): ...print 2 ... t=test() t() 1 Kent -- http://mail.python.org/mailman/listinfo/python-list
Re: changing __call__ on demand
Thanks; I didn't read close enough. :) -- Alan McIntyre ESRG LLC http://www.esrgtech.com Michael Hoffman wrote: Alan McIntyre wrote: class test(object): ...def __call1(self): ...print 1 ...__call__ = __call1 Is that what you were looking for? That still only allows him to have one call function per class. -- http://mail.python.org/mailman/listinfo/python-list