469,268 Members | 975 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,268 developers. It's quick & easy.

functions, classes, bound, unbound?

Here is some example code that produces an error:

class Test(object):
def greet():
print "Hello"

t = Test()
t.greet()
TypeError: greet() takes no arguments (1 given)

Ok. That makes sense. t.greet() is a "bound method", so something
automatically relays the instance object to greet(), and since greet()
is defined with no parameters-->Error.

Hmmm...I know from testing several examples that if I call a function
that's defined inside a class, and I use the class name preceding the
function call, then I have to send the instance manually. So, based
on that error message, I'll just call the method using the class name
and not send the instance object:

Test.greet()

TypeError: unbound method greet() must be called with Test instance as
first argument (got nothing instead)

Mar 25 '07 #1
14 2755
On 24 Mar 2007 20:24:36 -0700, 7stud <bb**********@yahoo.comwrote:
Here is some example code that produces an error:
[snip]

Why do people absolutely *love* to do weird and ugly things with
Python? Contests apart, I don't see lots of people trying this kind of
things on other (common) languages.

Say with me: "Python is powerful, but I'll use that power *only* for
beautiful and straightforward code."

Further reading:
http://www.python.org/doc/Humor.html#zen

--
Felipe.
Mar 25 '07 #2
On Sat, 24 Mar 2007 20:24:36 -0700, 7stud wrote:
Here is some example code that produces an error:

class Test(object):
def greet():
print "Hello"

t = Test()
t.greet()
TypeError: greet() takes no arguments (1 given)

Ok. That makes sense. t.greet() is a "bound method", so something
automatically relays the instance object to greet(), and since greet()
is defined with no parameters-->Error.

Hmmm...I know from testing several examples that if I call a function
that's defined inside a class, and I use the class name preceding the
function call, then I have to send the instance manually. So, based
on that error message, I'll just call the method using the class name
and not send the instance object:

Test.greet()

TypeError: unbound method greet() must be called with Test instance as
first argument (got nothing instead)

Is there a question hidden there somewhere, or are you just reporting on a
fact you have learned and are excited about?
Instance methods always need a self parameter, even if you call them from
the class. That's why you have to provide the instance by hand if you call
them from the class.

If you are trying to create a method that doesn't take a self argument,
have a look at the staticmethod function. There's also a classmethod
function as well.

--
Steven.

Mar 25 '07 #3
7stud wrote:
Here is some example code that produces an error:

class Test(object):
def greet():
print "Hello"

t = Test()
t.greet()
TypeError: greet() takes no arguments (1 given)
[snip]
Test.greet()

TypeError: unbound method greet() must be called with Test instance as
first argument (got nothing instead)
Methods in a class are generally expected to take an instance as their
first argument, but your greet() method takes no arguments. This is
because classes don't invoke the function directly, they convert it to
an 'unbound method' object::
>>class Test(object):
... def greet():
... print 'Hello'
...
>>Test.greet
<unbound method Test.greet>
>>Test.greet()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: unbound method greet() must be called with Test instance
as first argument (got nothing instead)

If you really want to get to the original function, there are a couple
of options. You can go through the class's __dict__, or you can wrap
your method with a @staticmethod decorator (which tells the class not to
wrap the function when you try to use it)::
>>Test.__dict__['greet']
<function greet at 0x00E708B0>
>>Test.__dict__['greet']()
Hello
>>class Test(object):
... @staticmethod
... def greet():
... print 'Hello'
...
>>Test.greet
<function greet at 0x00E7D2F0>
>>Test.greet()
Hello

STeVe
Mar 25 '07 #4
...classes don't invoke the function directly, they convert it to
an 'unbound method' object::
>>class Test(object):
... def greet():
... print 'Hello'
...
>>Test.greet
<unbound method Test.greet>
>>Test.greet()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: unbound method greet() must be called with Test instance
as first argument (got nothing instead)
I think I found the rule in the GvF tutorial, which is essentially
what the error message says:
-------
When an unbound user-defined method object is called, the underlying
function (im_func) is called, with the restriction that the first
argument must be an instance of the proper class (im_class) or of a
derived class thereof.
--------

So, if you call a function using the syntax TheClass.theMethod(),
then you are required to use an instance object as an argument.

In section 3.2 The Standard Class Hierarchy, it also says this:
-------
When a user-defined method object is created by retrieving a user-
defined function object from a class, its im_self attribute is None
and the method object is said to be unbound. When one is created by
retrieving a user-defined function object from a class via one of its
instances, its im_self attribute is the instance, and the method
object is said to be bound.
--------

In that first sentence, is he talking about retrieving the user-
defined function object from the class using the class name, e.g:

MyClass.someFunc

Is there some other way to retrieve a user-defined function object
from a class other than using the class name or an instance?

If you really want to get to the original function, there are a couple
of options.
No. Just trying to figure out how some things work.

Mar 25 '07 #5
On Mar 25, 9:13 am, "7stud" <bbxx789_0...@yahoo.comwrote:
MyClass.someFunc

Is there some other way to retrieve a user-defined function object
from a class other than using the class name or an instance?
What Steven B. already said, MyClass.__dict__['someFunc'], is a
different way than MyClass.someFunc that produces different results.
Since the method is an attribute of a class, what other kinds of means
are you expecting to be possible?

You can use reflection to dig up MyClass-object from the module
dictionary if referring to object or class by name in the code is
something you want to get rid of.

Mar 25 '07 #6
On Mar 25, 3:00 am, irs...@gmail.com wrote:
On Mar 25, 9:13 am, "7stud" <bbxx789_0...@yahoo.comwrote:
MyClass.someFunc
Is there some other way to retrieve a user-defined function object
from a class other than using the class name or an instance?

What Steven B. already said, MyClass.__dict__['someFunc'], is a
different way than MyClass.someFunc that produces different results.
That doesn't seem to fit what GvR was talking about. From this
example:

class Test(object):
def greet():
print "Hello"

methObj = Test.__dict__["greet"]
print methObj.im_self

I get this output:

Traceback (most recent call last):
File "test1.py", line 7, in ?
print methObj.im_self
AttributeError: 'function' object has no attribute 'im_self'

So it doesn't look like a method object gets created when you retrieve
a function from a class like that. Compare to:

class Test(object):
def greet():
print "Hello"

methObj = Test.greet
print methObj.im_self

output:
None
Since the method is an attribute of a class, what other kinds of means
are you expecting to be possible?
I'm just wondering why in this description:
----
When a user-defined method object is created by retrieving a user-
defined function object from a class, its im_self attribute is None
and the method object is said to be unbound. When one is created by
retrieving a user-defined function object from a class via one of its
instances, its im_self attribute is the instance, and the method
object is said to be bound.
-----
GvR didn't explicitly mention using the class name to retrieve the
function object in the first sentence. It seems to imply there are
other ways to retrieve the function object from the class that cause a
method object to be created.

Mar 25 '07 #7
En Sun, 25 Mar 2007 17:22:36 -0300, 7stud <bb**********@yahoo.com>
escribió:
On Mar 25, 3:00 am, irs...@gmail.com wrote:
>On Mar 25, 9:13 am, "7stud" <bbxx789_0...@yahoo.comwrote:
Is there some other way to retrieve a user-defined function object
from a class other than using the class name or an instance?

What Steven B. already said, MyClass.__dict__['someFunc'], is a
different way than MyClass.someFunc that produces different results.

methObj = Test.__dict__["greet"]
print methObj.im_self

Traceback (most recent call last):
File "test1.py", line 7, in ?
print methObj.im_self
AttributeError: 'function' object has no attribute 'im_self'
Because this way, you get a function, not a method. I'd say "read
something about descriptors" but...

Nicolas Bourbaki [a collective of french mathematicians writing under that
alias] said on a book about set theory: Any school boy can understand all
of this with a minimum of effort, but for truly understanding what we are
talking about, around four years of prior training on mathematics may be
required. (I can't find the exact citation).

I suggest first learn to use Python and then try to understand how it does
what it does, along the way, and looking for answers when you have a
question.

--
Gabriel Genellina

Mar 25 '07 #8
On Mar 25, 9:13 am, "7stud" <bbxx789_0...@yahoo.comwrote:
Is there some other way to retrieve a user-defined function object
from a class other than using the class name or an instance?
On Mar 25, 3:00 am, irs...@gmail.com wrote:
What Steven B. already said, MyClass.__dict__['someFunc'], is a
different way than MyClass.someFunc that produces different results.
7stud wrote:
That doesn't seem to fit what GvR was talking about. From this
example:

class Test(object):
def greet():
print "Hello"

methObj = Test.__dict__["greet"]
print methObj.im_self

I get this output:

Traceback (most recent call last):
File "test1.py", line 7, in ?
print methObj.im_self
AttributeError: 'function' object has no attribute 'im_self'

Yep. The thing in the class __dict__ is the original *function*. The
thing you get from something like ``Test.greet`` is the *method*.
Here's another way of looking at it::
>>class Test(object):
... pass
...
>>def greet():
... print 'Hello'
...
>>greet
<function greet at 0x00E718B0>
>>Test.greet = greet
Test.__dict__['greet']
<function greet at 0x00E718B0>
>>Test.__dict__['greet'] is greet
True

Note that ``Test.__dict__['greet']`` is the ``greet`` *function*, not
some wrapper of that function. When you access the class attribute
normally, Python creates an 'unbound method' object::
>>Test.greet
<unbound method Test.greet>
>>Test.greet is greet
False
>>Test.greet.im_func
<function greet at 0x00E718B0>
>>Test.greet.im_func is greet
True

See that ``Test.greet`` gives you an 'unbound method' object which just
wraps the real 'function' object (which is stored as the 'im_func'
attribute)? That's because under the covers, classes are actually using
doing something like this::
>>Test.__dict__['greet'].__get__(None, Test)
<unbound method Test.greet>
>>Test.greet == Test.__dict__['greet'].__get__(None, Test)
True

So if you want to get a method from a function, you can always do that
manually yourself::
>>greet.__get__(None, Test)
<unbound method Test.greet>

Hope that helps,

STeVe
Mar 25 '07 #9
7stud a écrit :
>...classes don't invoke the function directly, they convert it to
an 'unbound method' object::
(snip)
>
>If you really want to get to the original function, there are a couple
of options.

No. Just trying to figure out how some things work.
Most of Python's object model is documented here:

http://www.python.org/download/relea....3/descrintro/
http://users.rcn.com/python/download/Descriptor.htm
HTH

Mar 26 '07 #10
On Mar 25, 3:09 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Here's another way of looking at it::
>>class Test(object):
... pass
...
>>def greet():
... print 'Hello'
...
>>Test.greet = greet
Test.greet
<unbound method Test.greet>
Interesting. After playing around with that example a bit and finally
thinking I understood bound v. unbound, I found what appears to be an
anomaly:
------------
class Test(object):
pass

def greet(x):
print "hello"

Test.func = greet
print Test.func

t = Test()
print t.func

def sayBye(x):
print "bye"

t.bye = sayBye
print t.bye
------------output:
<unbound method Test.greet>
<bound method Test.greet of <__main__.Test object at 0x6dc50>>
<function sayBye at 0x624b0>

Why doesn't t.bye cause a method object to be created?

... under the covers, classes are actually using
doing something like this::
>>Test.__dict__['greet'].__get__(None, Test)
<unbound method Test.greet>
>>Test.greet == Test.__dict__['greet'].__get__(None, Test)
True
....via __getattribute_, right?
... if you want to get a method from a function, you can always do that
manually yourself::
>>greet.__get__(None, Test)
<unbound method Test.greet>
Manually creating a method object. Nice.

Mar 26 '07 #11
On Mar 26, 7:15 pm, "7stud" <bbxx789_0...@yahoo.comwrote:
On Mar 25, 3:09 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Here's another way of looking at it::
>>class Test(object):
... pass
...
>>def greet():
... print 'Hello'
...
>Test.greet = greet
Test.greet
<unbound method Test.greet>

Interesting. After playing around with that example a bit and finally
thinking I understood bound v. unbound, I found what appears to be an
anomaly:
------------
class Test(object):
pass

def greet(x):
print "hello"

Test.func = greet
print Test.func

t = Test()
print t.func

def sayBye(x):
print "bye"

t.bye = sayBye
print t.bye
------------output:
<unbound method Test.greet>
<bound method Test.greet of <__main__.Test object at 0x6dc50>>
<function sayBye at 0x624b0>

Why doesn't t.bye cause a method object to be created?
Because that would be bad and unexpected behaviour. I might want to
store callback functions to an object as attributes. It wouldn't make
sense for the functions to be bound to the container object when I'd
access them.

Of course, "Test.func = greet; print Test.func" is also "unexpected
behaviour" as Test.func is not same as Test.__dict__['func']. But it's
unexpected in a good way, because it facilitates the way classes are
usually used. The whole point of the magic is to make common idioms
simple.

Mar 26 '07 #12
On Mar 26, 5:08 am, Bruno Desthuilliers <bruno.
42.desthuilli...@wtf.websiteburo.oops.comwrote:
Most of Python's object model is documented here:

http://www.python.org/download/relea...Descriptor.htm
Thanks. I've looked at both of those, and the second one is very
good.

Mar 26 '07 #13
7stud a écrit :
On Mar 25, 3:09 pm, Steven Bethard <steven.beth...@gmail.comwrote:
>>Here's another way of looking at it::
> >>class Test(object):
... pass
...
> >>def greet():
... print 'Hello'
...
>>>>Test.greet = greet
Test.greet

<unbound method Test.greet>


Interesting. After playing around with that example a bit and finally
thinking I understood bound v. unbound, I found what appears to be an
anomaly:
------------
class Test(object):
pass

def greet(x):
print "hello"

Test.func = greet
print Test.func

t = Test()
print t.func

def sayBye(x):
print "bye"

t.bye = sayBye
print t.bye
------------output:
<unbound method Test.greet>
<bound method Test.greet of <__main__.Test object at 0x6dc50>>
<function sayBye at 0x624b0>

Why doesn't t.bye cause a method object to be created?
(technical answer - I leave to some guru the care to explain the
motivations for this behaviour)

Because t.bye is an attribute of instance t, not of class Test. A
descriptor object has to be a class attribute for the descriptor
protocol to be invoked.
Note that you can override __getattribute__ to change this - but this is
somewhat hackish, and will probably slow down things quite a bit.

FWIW, if you want to dynamically add a method to an instance:
inst.method = func.__get__(inst, inst.__class__)

Mar 27 '07 #14
On Mar 26, 6:49 pm, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
------------
class Test(object):
pass
def greet(x):
print "hello"
Test.func = greet
print Test.func
t = Test()
print t.func
def sayBye(x):
print "bye"
t.bye = sayBye
print t.bye
------------output:
<unbound method Test.greet>
<bound method Test.greet of <__main__.Test object at 0x6dc50>>
<function sayBye at 0x624b0>
Because t.bye is an attribute of instance t, not of class Test. A
descriptor object has to be a class attribute for the descriptor
protocol to be invoked.
Hurray! Like this:
t.func -__getattribute__() -__get__() -create method object and
return it
t.bye -__getattribute__() -return sayBye

FWIW, if you want to dynamically add a method to an instance:
inst.method = func.__get__(inst, inst.__class__)
Nice.
Mar 27 '07 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Jacek Generowicz | last post: by
99 posts views Thread by David MacQuigg | last post: by
15 posts views Thread by Paulo da Silva | last post: by
21 posts views Thread by ron | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.