473,395 Members | 1,578 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

substitution of a method by a callable object

Can I substitute a method of a class by a callable object (not a
function)? I can very easy insert my function in a class as a method,
but an object - can't.

I have the following:

class Foo(object):
pass

class Obj(object):
def __call__(self, obj_self):
print 'Obj'

def func(self):
print 'func'

f = Foo()
Foo.meth = func
f.meth() # all goes OK
Foo.meth = Obj()
f.meth() # I get TypeError: __call__() takes exactly 2 arguments (1
given)
Oct 22 '08 #1
6 1495
netimen wrote:
Can I substitute a method of a class by a callable object (not a
function)? I can very easy insert my function in a class as a method,
but an object - can't.
Yes you can and did.
class Foo(object):
pass

class Obj(object):
def __call__(self, obj_self):
print 'Obj'

def func(self):
print 'func'

f = Foo()
Foo.meth = func
f.meth() # all goes OK
Foo.meth = Obj()
f.meth() # I get TypeError: __call__() takes exactly 2 arguments (1
given)
So either remove the unused obj_self parameter from __call__ or pass
something -- anything -- to be bound to it.
f.meth(1) for instance, works fime (in 3.0 at least)

Oct 22 '08 #2
On Oct 22, 12:13*pm, netimen <neti...@gmail.comwrote:
Can I substitute a method of a class by a callable object (not a
function)? I can very easy insert my function in a class as a method,
but an object - can't.

I have the following:

class Foo(object):
* * pass

class Obj(object):
* * def __call__(self, obj_self):
* * * * print 'Obj'

def func(self):
* * print 'func'

f = Foo()
Foo.meth = func
f.meth() # all goes OK
Foo.meth = Obj()
f.meth() # I get TypeError: __call__() takes exactly 2 arguments (1
given)
You have to wrap it as an (unbound) instance method explicitly:

from types import MethodType
Foo.meth = MethodType(Obj(), None, Foo)
f.meth()

For normal functions this seems to be done implicitly (of course you
can do it explicitly if you want):
>>Foo.meth = func
print Foo.meth
<unbound method Foo.func>

George
Oct 22 '08 #3
On 22 §à§Ü§ä, 20:46, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
netimen a ¨¦crit :
Can I substitute a method of a class by a callable object (not a
function)? I can very easy insert my function in a class as a method,
but an object - can't.

functions implement the descriptor protocol so when looked up as class
attributes, the lookup invoke their __get__ method, which in turn
returns a method object (which is a thin wrapper around the function,
the class and the instance).

You can either build the method manually (as Georges explained), or make
your own Obj class a proper descriptor:

from types import MethodType

class Obj(object):
__name__ = "Obj" # for Method.__repr_

def __call__(self, obj_self):
print 'Obj'

def __get__(self, instance, cls):
return MethodType(self, instance, cls)

HTH
thanks!
Oct 22 '08 #4
George Sakkis wrote:
On Oct 22, 12:13 pm, netimen <neti...@gmail.comwrote:
>Can I substitute a method of a class by a callable object (not a
function)? I can very easy insert my function in a class as a method,
but an object - can't.

I have the following:

class Foo(object):
pass

class Obj(object):
def __call__(self, obj_self):
print 'Obj'

def func(self):
print 'func'

f = Foo()
Foo.meth = func
f.meth() # all goes OK
Foo.meth = Obj()
f.meth() # I get TypeError: __call__() takes exactly 2 arguments (1
given)

You have to wrap it as an (unbound) instance method explicitly:
Nope. As the error message says, the method was called with nothing
provided to be bound to the extraneous parameter obj_self. Either
provide an arg, such as with f.meth(1), *or* delete obj_self and 'Obj'
is printed, with both 2.5 and 3.0.

Oct 22 '08 #5
On 23 ÏËÔ, 00:34, Terry Reedy <tjre...@udel.eduwrote:
George Sakkis wrote:
On Oct 22, 12:13 pm, netimen <neti...@gmail.comwrote:
Can I substitute a method of a class by a callable object (not a
function)? I can very easy insert my function in a class as a method,
but an object - can't.
I have the following:
class Foo(object):
š š pass
class Obj(object):
š š def __call__(self, obj_self):
š š š š print 'Obj'
def func(self):
š š print 'func'
f = Foo()
Foo.meth = func
f.meth() # all goes OK
Foo.meth = Obj()
f.meth() # I get TypeError: __call__() takes exactly 2 arguments (1
given)
You have to wrap it as an (unbound) instance method explicitly:

Nope. šAs the error message says, the method was called with nothing
provided to be bound to the extraneous parameter obj_self. šEither
provide an arg, such as with f.meth(1), *or* delete obj_self and 'Obj'
is printed, with both 2.5 and 3.0.
OK, I have implemented Bruno Desthuilliers example. But there is
another question: can I having a method determine if it is an instance
of given class. So:

class Obj(object):
__name__ = "Obj" # for Method.__repr_

def __call__(self, obj_self):
print 'Obj'

def __get__(self, instance, cls):
return MethodType(self, instance, cls)

class Foo(object):
pass

Foo.meth = Obj()

## in some another place of code
if isinstance(Foo.meth, Obj): # doesn't work because type(Foo.meth) is
now 'instancemethod'
...

Can I determine that?
Oct 22 '08 #6
On 23 §à§Ü§ä, 00:26, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
netimen a ¨¦crit :
(snip)
OK, I have implemented Bruno Desthuilliers example. But there is
another question: can I having a method determine if it is an instance
of given class. So:

As the name imply, a method is usually, well, an instance of type
'method' !-)
class Obj(object):
(snip)
class Foo(object):
pass
Foo.meth = Obj()
## in some another place of code
if isinstance(Foo.meth, Obj): # doesn't work because type(Foo.meth) is
now 'instancemethod'

Indeed. I suppose what you want is to know if the callable wrapped by
the method is an instance of Obj ?
Can I determine that?

Yeps. Test the im_func attribute of the method:

if isinstance(Foo.meth.im_func, Obj): print "yadda"

But you'd better put this in a try/except block, because a callable
attribute of a class is not necessarily a method - and so it may not
have an im_func attribute.

Also, may I ask why you want to check this ? Not that it's necessarily
wrong, but real use case for typechecking are pretty rare.
Thanks! I have wasted much time playing with different Foo.meth trying
to get to Obj through them. But im_func was one of the fields I
haven't checked )

Indeed, I have managed already without that. The task was to
substitute __str__ method by a complex formatter. It called a low-
level formatter, a function wich returned simple str(self). That
function could be called with objects with substituted formatters and
with simple objects. So to avoid recursion I wanted to check wether
the formatter of my object was substituted.
Oct 23 '08 #7

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

Similar topics

21
by: Roy Smith | last post by:
I've got a function which gets passed a call-back function as a parameter. I want to check to make sure the thing passed in is indeed callable. Is: assert '__call__' in dir (param) the...
7
by: Edward Diener | last post by:
This simple code example gives me the message, "TypeError: 'staticmethod' object is not callable". class X(object): def Y(x): print x Y = staticmethod(Y) ad = { 1 : Y } def Z(self):...
3
by: Apple | last post by:
Hi I am a bit new to python. I was wondering if there is a way to determine whether or not a given string is a member method of a given object: def is_a_method(self, attr_name): 'returns True...
4
by: Don | last post by:
I think "macro substitution" is the correct term for what I want to do, but, to be sure, here is a description of what I'd like to know is possible: I want to be able to create a create an object...
44
by: gregory.petrosyan | last post by:
Hello everybody! I have little problem: class A: def __init__(self, n): self.data = n def f(self, x = ????) print x All I want is to make self.data the default argument for self.f(). (I
17
by: Eric Brunel | last post by:
Hi all, I just stepped on a thing that I can't explain. Here is some code showing the problem: ----------------------------- class C: f = None def __init__(self): if self.f is not None:
6
by: Rob Cowie | last post by:
Hi all, Is there a simple way to call every method of an object from its __init__()? For example, given the following class, what would I replace the comment line in __init__() with to result...
6
by: Sagari | last post by:
Greetings, Can someone suggest an efficient way of calling method whose name is passed in a variable? Given something like: class X: #... def a(self):
6
by: Manuel Ebert | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Luca, use type(something).__name__ , e.g. True True True
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
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...
0
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...
0
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...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...
0
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...
0
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...

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.