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 11 1852
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
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
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
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
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/pyt...ry/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
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
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.
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
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/
Le Sun, 13 Feb 2005 13:19:03 -0500, Hans Nowak a écrit : 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 # self.__call__ is bound ... def __call1(self): ... print 1 ... def __call__(self): # self.__call__ is rebound ... print 2 ... .>>> t = test() .>>> t() 2
2 because the last defined __call__ wins. Try dir(t) If I take out the __call__ method completely and only set it in __init__, I get a TypeError saying that test is not callable.
This seems logical. 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}
Are you sure that if you add a __call__() method, it will still work
fine ?
Regards
F. Petitjean wrote: Le Sun, 13 Feb 2005 13:19:03 -0500, Hans Nowak a écrit :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}
Are you sure that if you add a __call__() method, it will still work fine ?
Simple enough to check, isn't it?
py> class C:
.... def __init__(self):
.... self.__call__ = lambda: "__init__"
.... def __call__(self):
.... return "__call__"
....
py> C()()
'__init__'
Old-style classes lookup methods like __call__ on the instance[1].
New-style classes look them up on the type:
py> class C:
.... def __init__(self):
.... self.__iter__ = lambda: iter(["__init__"])
.... def __iter__(self):
.... return iter(["__call__"])
....
py> list(C())
['__init__']
py> class C(object):
.... def __init__(self):
.... self.__iter__ = lambda: iter(["__init__"])
.... def __iter__(self):
.... return iter(["__call__"])
....
py> list(C())
['__call__']
AFAICT, non-magic methods are looked up on instance first:
py> class C:
.... def __init__(self):
.... self.f = lambda: "__init__"
.... def f(self):
.... return "__call__"
....
py> C().f()
'__init__'
py> class C(object):
.... def __init__(self):
.... self.f = lambda: "__init__"
.... def f(self):
.... return "__call__"
....
py> C().f()
'__init__'
STeVe
[1] Well, they look there first. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Patrick Lioi |
last post by:
def foo(): pass
foo is a function
foo is a callable object
foo has method __call__ defined
foo.__call__ is a function
foo.__call__ is a callable object
foo.__call__ has method __call__...
|
by: Robert Ferrell |
last post by:
I have a question about assigning __call__ to an instance to make that
instance callable. I know there has been quite a bit of discussion
about this, and I've read all I can find, but I'm still...
|
by: Rahul |
last post by:
Consider the following:
def a(x):
return x+1
def b(f):
def g(*args,**kwargs):
for arg in args:
print arg
return f(*args,**kwargs)
return g
|
by: ncf |
last post by:
I have a feeling that this is highly unlikely, but does anyone in here
know if it's possible to directly call a module, or will I have to wrap
it up in a class?
i.e.,
import MyMod...
|
by: Kent Johnson |
last post by:
I am learning about metaclasses and there is something that confuses me.
I understand that if I define a __call__ method for a class, then instances of the class become callable using function...
|
by: Chris Hills |
last post by:
A lesson in Posting
How many C.L.C group posters does it take to change a C light bulb?
1 to change the light bulb and to post that the light bulb has been
changed
14 to share similar...
|
by: Gigs_ |
last post by:
from Tkinter import *
from tkFileDialog import askopenfilename
from tkColorChooser import askcolor
from tkMessageBox import askquestion, showerror
from tkSimpleDialog import askfloat
demos...
|
by: skip |
last post by:
I don't personally use __call__ methods in my classes, but I have
encountered it every now and then here at work in code written by other
people. The other day I replaced __call__ with a more...
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |