473,670 Members | 2,353 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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_metho d accordingly, but I find that somewhat
sub-optimal. Is there a way to change __call__ after class creation?

Stefan
Jul 18 '05 #1
11 1870
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_metho d accordingly, but I find that somewhat
sub-optimal. Is there a way to change __call__ after class creation?

Stefan


Jul 18 '05 #2
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
Jul 18 '05 #3
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
Jul 18 '05 #4

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
Jul 18 '05 #5
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
Jul 18 '05 #6
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
Jul 18 '05 #7
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.

Jul 18 '05 #8
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
Jul 18 '05 #9
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/

Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
2499
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__ defined
5
2364
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 confused. I'd like to have a factory class that takes a string argument and returns the appropriate factory method based on that string. I'd like the instances to be callable. Like this: fact = Factory('SomeThing') aSomeThing = fact(some...
8
1711
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
7
1769
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 MyMod.whatever = "Hi?" MyMod("meow mix")
5
1358
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 syntax: >>> class Foo(object): ... def __call__(self): ... print 'Called Foo' ... >>> f=Foo() >>> f()
18
2199
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 experiences of changing light bulbs and how the light bulb could have been changed differently
7
2176
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 = { 'Open': askopenfilename, 'Color': askcolor, 'Query': lambda: askquestion('Warning', 'You typed
17
1666
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 obvious method name, so now instead of executing obj(foo, bar, baz) the code in question is obj.execute(foo, bar, baz)
0
8388
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8663
tracyyun
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7423
agi2029
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6218
isladogs
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5687
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4215
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4396
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2804
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2046
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.