473,693 Members | 2,747 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

__call__ considered harmful or indispensable?


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)

In this case there was a bug. Depending on inputs, sometimes obj
initialized to a class, sometimes an instance of that class. (I fixed that
too while I was at it.) The problem was that the use of __call__ obscured
the underlying bug by making the instance as well as the class callable.

In this particular case it was clearly unnecessary and just obfuscated the
code. I'm wondering, are there some general cases where __call__ methods of
a user-defined class are simply indispensable?

Thx,

Skip

Aug 2 '07 #1
17 1668
On 2007-08-02, sk**@pobox.com <sk**@pobox.com wrote:
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)

In this case there was a bug. Depending on inputs, sometimes
obj initialized to a class, sometimes an instance of that
class. (I fixed that too while I was at it.) The problem was
that the use of __call__ obscured the underlying bug by making
the instance as well as the class callable.

In this particular case it was clearly unnecessary and just
obfuscated the code. I'm wondering, are there some general
cases where __call__ methods of a user-defined class are simply
indispensable?
In C++ they are called functors, and they are very useful as
surrogate functions with state. I haven't seen them used in the
same way in Python much, because Python has more immediate
solutions to (most of) these problems.

Here's a (somewhat goofy) example:

class is_consecutive( object):
def __init__(self, seed, compare=operato r.lt):
self.last_value = seed
self.compare = compare
def __call__(self, total, value):
if total is False:
return False
lv = self.last_value
self.last_value = value
return self.compare(lv , value):

a = range(15)
>>reduce(is_con secutive(0), a)
True
>>reduce(is_con secutive(0), a + [1,2])
False

It's been a while since I had to be in the STL mindset, so I
couldn't think of a better example.

--
Neil Cerutti
This is not a book to be put down lightly. It should be thrown with great
force. --Dorothy Parker
Aug 2 '07 #2
On 2007-08-02, Neil Cerutti <ho*****@yahoo. comwrote:
On 2007-08-02, sk**@pobox.com <sk**@pobox.com wrote:
>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)

In this case there was a bug. Depending on inputs, sometimes
obj initialized to a class, sometimes an instance of that
class. (I fixed that too while I was at it.) The problem was
that the use of __call__ obscured the underlying bug by making
the instance as well as the class callable.

In this particular case it was clearly unnecessary and just
obfuscated the code. I'm wondering, are there some general
cases where __call__ methods of a user-defined class are simply
indispensabl e?

In C++ they are called functors, and they are very useful as
surrogate functions with state. I haven't seen them used in the
same way in Python much, because Python has more immediate
solutions to (most of) these problems.

Here's a (somewhat goofy) example:

class is_consecutive( object):
def __init__(self, seed, compare=operato r.lt):
That was supposed to be operator.le, not lt. I forgot to repaste after
fixing that bug.
self.last_value = seed
self.compare = compare
def __call__(self, total, value):
if total is False:
return False
lv = self.last_value
self.last_value = value
return self.compare(lv , value):

a = range(15)
>>>reduce(is_co nsecutive(0), a)
True
>>>reduce(is_co nsecutive(0), a + [1,2])
False

It's been a while since I had to be in the STL mindset, so I
couldn't think of a better example.

--
Neil Cerutti
The pastor will preach his farewell message, after which the choir will sing,
"Break Forth Into Joy." --Church Bulletin Blooper
Aug 2 '07 #3
On 8/2/07, Neil Cerutti <ho*****@yahoo. comwrote:
On 2007-08-02, sk**@pobox.com <sk**@pobox.com wrote:
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)

In this case there was a bug. Depending on inputs, sometimes
obj initialized to a class, sometimes an instance of that
class. (I fixed that too while I was at it.) The problem was
that the use of __call__ obscured the underlying bug by making
the instance as well as the class callable.

In this particular case it was clearly unnecessary and just
obfuscated the code. I'm wondering, are there some general
cases where __call__ methods of a user-defined class are simply
indispensable?

In C++ they are called functors, and they are very useful as
surrogate functions with state. I haven't seen them used in the
same way in Python much, because Python has more immediate
solutions to (most of) these problems.
I don't think I've ever written one (in Python) except to demonstrate
how it worked. Pythons built in functions have all the functionality
that you'd have to use a functor for in C++.
Aug 2 '07 #4
sk**@pobox.com schrieb:
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)

In this case there was a bug. Depending on inputs, sometimes obj
initialized to a class, sometimes an instance of that class. (I fixed that
too while I was at it.) The problem was that the use of __call__ obscured
the underlying bug by making the instance as well as the class callable.

In this particular case it was clearly unnecessary and just obfuscated the
code. I'm wondering, are there some general cases where __call__ methods of
a user-defined class are simply indispensable?
Thanks to closures and bound methods, I don't think that there is a
case where you can't "fake" the missing __call__ at least when it comes
to call-backs. So in the end, you can always work around that. But if
you don't need to...

Se the gnosis multimethods for an implementation that makes sensible use
of the __call__-operator in my opinion.

diez
Aug 2 '07 #5
sk**@pobox.com writes:
In this particular case it was clearly unnecessary and just obfuscated the
code. I'm wondering, are there some general cases where __call__ methods of
a user-defined class are simply indispensable?
I don't know about "indispensa ble" but __call__ is convenient sometimes
and I do use it. I've wished that modules supported call, so I could
say

import foo
x = foo(3)

instead of having to say x=foo.foo(3) or something like that.
Aug 2 '07 #6
sk**@pobox.com a écrit :
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)

In this case there was a bug. Depending on inputs, sometimes obj
initialized to a class, sometimes an instance of that class. (I fixed that
too while I was at it.) The problem was that the use of __call__ obscured
the underlying bug by making the instance as well as the class callable.
I don't quite get the point here. A concrete example would be welcome.
In this particular case it was clearly unnecessary and just obfuscated the
code. I'm wondering, are there some general cases where __call__ methods of
a user-defined class are simply indispensable?
"simply indispensable", I don't know. FWIW, most of the features of
Python are not "simply indispensable" !-)

Most of what you can do with a callable instance can be done with
closures (and is usually done so in FPLs), but given Python's OO nature,
it's sometimes clearer and simpler to use callable instances than
closures. One example that comes to mind is partial application that I
first saw implemented with closures in Django, then as a class in PEP
309's example. Another common use case is parameterized function
decorators, that are often cleaner (IMHO) when implemented as classes
with __call__ than with three levels of nested funcs. In both cases,
closures and callables implementations are functionally equivalent, and
this is transparent for user code, so it's mostly a matter of
readability and personal preferences...

As far as I'm concerned, I do use __call__ "every know and then".
Usually, because I had to pass a callable to some API and needed to
parameterize it (IOW, ad-hoc partial application).
Aug 2 '07 #7
Paul Rubin a écrit :
sk**@pobox.com writes:
>>In this particular case it was clearly unnecessary and just obfuscated the
code. I'm wondering, are there some general cases where __call__ methods of
a user-defined class are simply indispensable?


I don't know about "indispensa ble" but __call__ is convenient sometimes
and I do use it. I've wished that modules supported call, so I could
say

import foo
x = foo(3)

instead of having to say x=foo.foo(3) or something like that.
from foo import foo
x = foo(3)

Or did I miss the point ???
Aug 2 '07 #8
Bruno Desthuilliers <bd************ *****@free.quel quepart.frwrite s:
from foo import foo
x = foo(3)

Or did I miss the point ???
The foo module might define a bunch of additional functions that you
still want to be able to access in qualified form. For example it
would somewhat clean up the interface to the python random module if
you could say

import random
x = random() # get a random float between 0 and 1

while still having access to random.shuffle, random.choice, etc.
Aug 2 '07 #9
Bruno Desthuilliers wrote:
>
Most of what you can do with a callable instance can be done with
closures (and is usually done so in FPLs), but given Python's OO nature,
it's sometimes clearer and simpler to use callable instances than
closures.
Indeed. I think __call__ has been neglected as closures have become
more widely used. In all cynicism, however, I'd argue that with
Python's very usable implementation of object-orientation, classes
with __call__ methods frequently make for clearer demonstrations of
solutions than closures do, despite requiring slightly more characters
of source code, and in contrast to the apparent fashion for using
closures for showing off more or less everything these days (despite
various pitfalls which may seem counter-intuitive to the beginner).

Paul

Aug 2 '07 #10

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

Similar topics

7
2501
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
9
1565
by: mike420 | last post by:
map(lambda f: f(1), ) Oh, OK, it was a typo (1 instead of i). I take it all back (for now). It was an honest mistake, not a troll! Still, I think it should be instead of
4
1661
by: Pete Forman | last post by:
Ian Hickson's essay at http://www.hixie.ch/advocacy/xhtml and many others argue that XHTML served as text/html should be considered harmful. I'm looking for any evidence that this is really so. As far as I can see it is only difficult. Is it harmful if done correctly? If XHTML 1.0 Strict is served as text/html with a DOCTYPE declaration but without an XML declaration then it should be rendered in
0
8549
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
8970
jinu1996
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8815
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6475
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
5824
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
4332
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...
1
2989
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
2245
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
1967
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.