functions, classes, bound, unbound?
Steven Bethard
steven.bethard at gmail.com
Sun Mar 25 17:09:02 EDT 2007
On Mar 25, 9:13 am, "7stud" <bbxx789_0... at yahoo.com> wrote:
> 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... at 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
More information about the Python-list
mailing list