If a variable refers to either a function or a class method, how can I find out which one it is and get the class type in case it is a class method especially when the class
At the time you are calling get_info(__init__)
(inside class definition) the __init__
is an ordinary function.
def get_info(function_or_method):
print function_or_method
class Foo(object):
def __init__(self):
pass
get_info(__init__) # function
def bar():
pass
get_info(Foo.__init__) # unbound method
get_info(Foo().__init__) # bound method
get_info(bar) # function
Output (CPython, IronPython):
<function __init__ at ...>
<unbound method Foo.__init__>
<bound method Foo.__init__ of <__main__.Foo object at ...>>
<function bar at ...>
Output (Jython):
<function __init__ 1>
<unbound method Foo.__init__>
<method Foo.__init__ of Foo instance 2>
<function bar 3>
To reemphasize a point which J.F. Sebastian alluded to, I want to be able to distinguish it when the function is being declared within the class (when the type I am getting is a function and not a bound or unbound method). ie. where the first call to
get_info(__init__)
happens I would like to be able to detect that its a method being declared as a part of a class.This question came up since I am putting a decorator around it and it gets a handle to the init function and I can't actually figure out if a method is being declared within a class or as a stand alone function
You can't. J.F. Sebastian's answer is still 100% applicable. When the body of the class definition is being executed, the class itself doesn't exist yet. The statements (the __init__
function definition, and the get_info(__init__)
call) happen in a new local namespace; at the time the call to get_info
occurs, __init__
is a reference to the function in that namespace, which is indistinguishable from a function defined outside of a class.
You can distinguish between the two by checking the type:
>>> type(bar)
<type 'function'>
>>> type(Foo.__init__)
<type 'instancemethod'>
or
>>> import types
>>> isinstance(bar, types.FunctionType)
True
>>> isinstance(bar, types.UnboundMethodType)
True
which is the way you'd do it in an if
statement.
Also, you can get the class from the im_class
attribute of the method:
>>> Foo.__init__.im_class
__main__.Foo