473,411 Members | 2,030 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,411 software developers and data experts.

Dynamic class methods misunderstanding

Hello all,

I have a misunderstanding about dynamic class methods. I don't expect
this behavior:

In [2]: class test:
...: def __init__(self, method):
...: self.method = method
...: self.method()
...:

In [3]: def m(self): print self
...:

In [4]: test(m)
---------------------------------------------------------------------------
exceptions.TypeError Traceback (most recent call
last)

/cygdrive/c/Documents and Settings/Wmill/<console>

/cygdrive/c/Documents and Settings/Wmill/<console> in __init__(self, method)

TypeError: m() takes exactly 1 argument (0 given)
-----------------------------------------------------------------------------

Why doesn't m get the implicit self parameter in the self.method()
call? How would I make it a proper member of the class, so that a
self.method() call would work with the above "m" function?

Peace
Bill Mill
bill.mill at gmail.com
Jul 18 '05 #1
15 1660
Le Fri, 28 Jan 2005 10:20:30 -0500, Bill Mill a écrit :
Hello all,

I have a misunderstanding about dynamic class methods. I don't expect
this behavior:

In [2]: class test:
...: def __init__(self, method):
...: self.method = method
...: self.method()
...:

In [3]: def m(self): print self
...:

In [4]: test(m)
---------------------------------------------------------------------------
exceptions.TypeError Traceback (most recent call
last)

/cygdrive/c/Documents and Settings/Wmill/<console>

/cygdrive/c/Documents and Settings/Wmill/<console> in __init__(self, method)

TypeError: m() takes exactly 1 argument (0 given)
-----------------------------------------------------------------------------

Why doesn't m get the implicit self parameter in the self.method()
call? How would I make it a proper member of the class, so that a
self.method() call would work with the above "m" function? The "def m(self):" was not properly indented. So here, "m" is a module level
function, not a method of your class.
Peace
Bill Mill
bill.mill at gmail.com

Jul 18 '05 #2
>
Why doesn't m get the implicit self parameter in the self.method()
call? How would I make it a proper member of the class, so that a
self.method() call would work with the above "m" function?


Use new.instancemethod:

import new

class Test:
def __init__(self, method):
self.m = new.instancemethod(method, self, Test)

def m(self):
print self

Test(m).m()
--
Regards,

Diez B. Roggisch
Jul 18 '05 #3
I see what you're attempting to do. However, your code, if it DID run,
would result in a method being added to the object, not the object's
class! Modify the class itself, not the object, as follows:

|class Test:
| def __init__(self):
| self.method()
|
|def m(self):
| print self
|
|setattr(Test, 'method', m)
|Test()

Jul 18 '05 #4
Bill Mill wrote:
Hello all,

I have a misunderstanding about dynamic class methods. I don't expect
this behavior:

In [2]: class test:
...: def __init__(self, method):
...: self.method = method
...: self.method()
...:

In [3]: def m(self): print self
...: [...]
TypeError: m() takes exactly 1 argument (0 given)
-----------------------------------------------------------------------------

Why doesn't m get the implicit self parameter in the self.method()
call? How would I make it a proper member of the class, so that a
self.method() call would work with the above "m" function?


m is a function. When you assign it to self.method, it's still a
function. You don't create a new method that way; all you have is a new
attribute called 'method' containing the function.

To add m as a new method to the *class*, do this:
class test: .... def __init__(self, method):
.... self.__class__.method = method
.... self.method()
.... def m(self): print self .... test(m) <__main__.test instance at 0x0192ED78>
<__main__.test instance at 0x0192ED78>


To add m as a new method to the *instance*, use new.instancemethod, as
Diez B. Roggisch already pointed out.

HTH,

--
Hans Nowak
http://zephyrfalcon.org/

Jul 18 '05 #5
Diez,

On Fri, 28 Jan 2005 16:57:37 +0100, Diez B. Roggisch <de*********@web.de> wrote:

Why doesn't m get the implicit self parameter in the self.method()
call? How would I make it a proper member of the class, so that a
self.method() call would work with the above "m" function?


Use new.instancemethod:

import new

class Test:
def __init__(self, method):
self.m = new.instancemethod(method, self, Test)


Beautiful! thank you very much. Looking into the "new" module in
python 2.4, that's equivalent to:

self.m = type(self.__init__)(method, self, Test)

I didn't know that you could call types to create another type.

Peace
Bill Mill
bill.mill at gmail.com
Jul 18 '05 #6
Hans,
On Fri, 28 Jan 2005 11:09:16 -0500, Hans Nowak <ha**@zephyrfalcon.org> wrote:
<snip>

m is a function. When you assign it to self.method, it's still a
function. You don't create a new method that way; all you have is a new
attribute called 'method' containing the function.

I figured as much; I just didn't know how to add it as a method.
To add m as a new method to the *class*, do this:
>>> class test: ... def __init__(self, method):
... self.__class__.method = method
... self.method()
... >>> def m(self): print self ... >>> test(m) <__main__.test instance at 0x0192ED78>
<__main__.test instance at 0x0192ED78>


When I run it, I only get one call to m, which is how I would expect
python to work; I assume the double printing here is a typo?
>>>


To add m as a new method to the *instance*, use new.instancemethod, as
Diez B. Roggisch already pointed out.


Thanks, you helped me understand it a lot.

Peace
Bill Mill
bill.mill at gmail.com
Jul 18 '05 #7
Kamilche,
On Fri, 28 Jan 2005 08:10:07 -0800 (PST), Kamilche
<kl*******@comcast.net> wrote:
I see what you're attempting to do. However, your code, if it DID run,
would result in a method being added to the object, not the object's
class! Modify the class itself, not the object, as follows:

|class Test:
| def __init__(self):
| self.method()
|
|def m(self):
| print self
|
|setattr(Test, 'method', m)
|Test()

beautiful; so this appears to be equivalent to the __class__ method
that Hans suggested.

Thanks a lot.

Peace
Bill Mill
bill.mill at gmail.com
--
http://mail.python.org/mailman/listinfo/python-list

Jul 18 '05 #8
Bill Mill wrote:
On Fri, 28 Jan 2005 11:09:16 -0500, Hans Nowak <ha**@zephyrfalcon.org> wrote:
<snip>
To add m as a new method to the *class*, do this:
>>> class test:

... def __init__(self, method):
... self.__class__.method = method
... self.method()
...
>>> def m(self): print self

...
>>> test(m)

<__main__.test instance at 0x0192ED78>
<__main__.test instance at 0x0192ED78>

When I run it, I only get one call to m, which is how I would expect
python to work; I assume the double printing here is a typo?


Actually, no. I'm using the interactive interpreter, so doing test(m)
results in two lines: the first one is printed by m, the second one is
the __repr__ of the test instance that was created, displayed by the
interpreter. Compare:
x = test(m) <__main__.test instance at 0x0192ED78> x

<__main__.test instance at 0x0192ED78>

--
Hans Nowak
http://zephyrfalcon.org/

Jul 18 '05 #9
On Fri, 28 Jan 2005 11:59:50 -0500, Hans Nowak <ha**@zephyrfalcon.org> wrote:
Bill Mill wrote:
On Fri, 28 Jan 2005 11:09:16 -0500, Hans Nowak <ha**@zephyrfalcon.org> wrote:
<snip>
>
To add m as a new method to the *class*, do this:

>>> class test:
... def __init__(self, method):
... self.__class__.method = method
... self.method()
...
>>> def m(self): print self
...
>>> test(m)
<__main__.test instance at 0x0192ED78>
<__main__.test instance at 0x0192ED78>

When I run it, I only get one call to m, which is how I would expect
python to work; I assume the double printing here is a typo?


Actually, no. I'm using the interactive interpreter, so doing test(m)
results in two lines: the first one is printed by m, the second one is
the __repr__ of the test instance that was created, displayed by the
interpreter. Compare:
>>> x = test(m) <__main__.test instance at 0x0192ED78> >>> x

<__main__.test instance at 0x0192ED78>


d'oh; that's how I ran it. Thanks a lot.
--
Hans Nowak
http://zephyrfalcon.org/

--
http://mail.python.org/mailman/listinfo/python-list

Jul 18 '05 #10
On Fri, 2005-01-28 at 11:17 -0500, Bill Mill wrote:
Beautiful! thank you very much. Looking into the "new" module in
python 2.4, that's equivalent to:

self.m = type(self.__init__)(method, self, Test)

I didn't know that you could call types to create another type.


Well, a type is essentially a class (in the OOP sense, not the python-
specific classobj sense). You can call a type or class to create an
instance of that class or type. Here, you call the 'instancemethod' type
to create an instance of type 'instancemethod'. Makes sense ... in
hindsight.

--
Craig Ringer

Jul 18 '05 #11

"Kamilche" <kl*******@comcast.net> wrote in message
news:11**********************@c13g2000cwb.googlegr oups.com...
I see what you're attempting to do. However, your code, if it DID run,
would result in a method being added to the object, not the object's
class! Modify the class itself, not the object, as follows:

|class Test:
| def __init__(self):
| self.method()
|
|def m(self):
| print self
|
|setattr(Test, 'method', m)
# this is a longwinded way to say
Test.method = m

setattr is for when you do *not* know the attribute name at coding time but
will have it in a string at run time, as in

methodname = 'method'
.......# some time later
setattr(Test, methodname, m)

Sometime Python makes things easier than people are initially willing to
believe ;-)
|Test()


Terry J. Reedy

Jul 18 '05 #12
On Fri, 28 Jan 2005 14:41:16 -0500, Terry Reedy <tj*****@udel.edu> wrote:

"Kamilche" <kl*******@comcast.net> wrote in message
news:11**********************@c13g2000cwb.googlegr oups.com...
I see what you're attempting to do. However, your code, if it DID run,
would result in a method being added to the object, not the object's
class! Modify the class itself, not the object, as follows:

|class Test:
| def __init__(self):
| self.method()
|
|def m(self):
| print self
|
|setattr(Test, 'method', m)
# this is a longwinded way to say
Test.method = m


That is the blindingly simple method that I wanted. I didn't know
before that I wanted it, but I'm sure of it now. Thank you very much,
terry.

setattr is for when you do *not* know the attribute name at coding time but
will have it in a string at run time, as in

methodname = 'method'
......# some time later
setattr(Test, methodname, m)

Sometime Python makes things easier than people are initially willing to
believe ;-)


I felt like there had to be a simpler solution.

Peace
Bill Mill
bill.mill at gmail.com
Jul 18 '05 #13
Bill Mill <bi*******@gmail.com> wrote:
...
class Test:
def __init__(self, method):
self.m = new.instancemethod(method, self, Test)


Beautiful! thank you very much. Looking into the "new" module in
python 2.4, that's equivalent to:

self.m = type(self.__init__)(method, self, Test)


Another approach with the same result is to exploit the fact that a
function is a descriptor:

self.m = method.__get__(self, Test)
Alex
Jul 18 '05 #14
On Sat, 29 Jan 2005 10:24:27 +0100, rumours say that al*****@yahoo.com
(Alex Martelli) might have written:
Bill Mill <bi*******@gmail.com> wrote:
...
> class Test:
> def __init__(self, method):
> self.m = new.instancemethod(method, self, Test)
Beautiful! thank you very much. Looking into the "new" module in
python 2.4, that's equivalent to:

self.m = type(self.__init__)(method, self, Test)

Another approach with the same result is to exploit the fact that a
function is a descriptor:

self.m = method.__get__(self, Test)


Almost true; not all builtin functions are descriptors though.

..>> import new
..>> f= new.instancemethod(divmod, 7, object)
..>> map(f, range(1,10,2))
[(7, 0), (2, 1), (1, 2), (1, 0), (0, 7)]
..>> f= divmod.__get__(7)

Traceback (most recent call last):
File "<pyshell#16>", line 1, in -toplevel-
f= divmod.__get__(7)
AttributeError: 'builtin_function_or_method' object has no attribute
'__get__'

I didn't run an extensive test, but it's possible that all builtin
functions are not descriptors.
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC1958)
I really should keep that in mind when talking with people, actually...
Jul 18 '05 #15
Christos TZOTZIOY Georgiou <tz**@sil-tec.gr> wrote:
...
> class Test:
> def __init__(self, method):
> self.m = new.instancemethod(method, self, Test)
...self.m = method.__get__(self, Test)
Almost true; not all builtin functions are descriptors though.

... AttributeError: 'builtin_function_or_method' object has no attribute
'__get__'

I didn't run an extensive test, but it's possible that all builtin
functions are not descriptors.


Indeed, many callables (builtin-functions, types, ...) are not
descriptors, so you can't call __get__ on them. But then, many
descriptors (statimethods, classmethods, ...) are not callable, so you
can't pass them as the first argument to instancemethod. Not having any
indication of what the author of class Test means to pass in as
"method", it's not clear whether Test(divmod) or Test(staticmethod(foo))
is more likely to be of interest to them as a use case. If ``method''
is a function, which is both a descriptor AND callable, either approach
works; otherwise, one has to pick an approach, or try both approaches
with a try/except.
Alex
Jul 18 '05 #16

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

Similar topics

8
by: Peter Collingbourne | last post by:
Hello I am trying to do some template metaprogramming involving enabling or disabling a method in a parameterised class based on some condition. I am trying to use the Boost enable_if mechanism...
4
by: Leslaw Bieniasz | last post by:
Cracow, 20.10.2004 Hello, As far as I understand, the generic programming basically consists in using templates for achieving a static polymorphism of the various code fragments, and their...
3
by: enki | last post by:
I have been doing some reading on dynamic bindind and polymorphism. I know the basics from what I have seen in books. The way virtual methods were explained was that they were used when methods...
0
by: nmichaud | last post by:
I am having a problem implementing some methods of a python class in C. The class is defined in python, but I would like to rewrite some methods in c. Here is an example of what I want to do: ...
60
by: Peter Olcott | last post by:
I need to know how to get the solution mentioned below to work. The solution is from gbayles Jan 29 2001, 12:50 pm, link is provided below: >...
0
by: Pascal Costanza | last post by:
Dynamic Languages Day @ Vrije Universiteit Brussel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Monday, February 13, 2006, VUB Campus Etterbeek The VUB (Programming Technology Lab,...
11
by: Sean M. DonCarlos | last post by:
I have an unmanaged Win32 app that looks up the name of a DLL (unknown at compile time) from an external location, loads it with LoadLibrary, and then uses GetProcAddress on three exported...
6
by: DaTurk | last post by:
Hi, I have three interfaces lets call them parent, child-A, and child-B. I want to have one variable, that can be either child-A, or child-B at run time. I just can't seem to figure out how to...
16
by: manatlan | last post by:
I've got an instance of a class, ex : b=gtk.Button() I'd like to add methods and attributes to my instance "b". I know it's possible by hacking "b" with setattr() methods. But i'd like to do...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
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,...
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...
0
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,...
0
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...

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.