如何区分函数和类方法?

Dha*_*ene 6 python reflection metaprogramming

如果一个变量指的是一个函数或一个类的方法,我怎么能找到它是哪一个,并得到了类类型的情况下,特别是当类仍然被宣布为在给定的例子一个类的方法.

例如.

def get_info(function_or_method):
    print function_or_method

class Foo(object):
    def __init__(self):
        pass

    get_info(__init__)

def bar():
    pass

get_info(bar)
Run Code Online (Sandbox Code Playgroud)

在David和JF Sebastian的前两个回复之后更新问题 为了再次强调JF Sebastian提到的一个观点,我希望能够在类中声明函数时区分它(当我得到的类型是函数时而不是绑定或未绑定的方法).即.在第一次调用get_info(__init__)发生的地方,我希望能够检测到它的方法被声明为类的一部分.

这个问题出现了,因为我在它周围放了一个装饰器,它获得了init函数的句柄,我实际上无法弄清楚方法是在一个类中声明还是作为一个独立的函数

Dav*_*d Z 12

您可以通过检查类型来区分这两者:

>>> type(bar)
<type 'function'>
>>> type(Foo.__init__)
<type 'instancemethod'>
Run Code Online (Sandbox Code Playgroud)

要么

>>> import types
>>> isinstance(bar, types.FunctionType)
True
>>> isinstance(bar, types.UnboundMethodType)
True
Run Code Online (Sandbox Code Playgroud)

这是你在一份if声明中这样做的方式.

此外,您可以从im_class方法的属性获取类:

>>> Foo.__init__.im_class
__main__.Foo
Run Code Online (Sandbox Code Playgroud)


jfs*_*jfs 9

在你调用时get_info(__init__)(在类定义中),这__init__是一个普通的函数.

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
Run Code Online (Sandbox Code Playgroud)

输出(CPython,IronPython):

<function __init__ at ...>
<unbound method Foo.__init__>
<bound method Foo.__init__ of <__main__.Foo object at ...>>
<function bar at ...>
Run Code Online (Sandbox Code Playgroud)

输出(Jython):

<function __init__ 1>
<unbound method Foo.__init__>
<method Foo.__init__ of Foo instance 2>
<function bar 3>
Run Code Online (Sandbox Code Playgroud)


Mil*_*les 4

为了再次强调 JF Sebastian 提到的一点,我希望能够在类中声明函数时(当我得到的类型是函数而不是绑定或未绑定方法时)区分它。IE。在第一次调用get_info(__init__)发生的地方,我希望能够检测到它是一个被声明为类的一部分的方法。

出现这个问题是因为我在它周围放置了一个装饰器,它获得了 init 函数的句柄,而我实际上无法弄清楚一个方法是在类中声明还是作为独立函数声明

你不能。JF Sebastian 的回答仍然 100% 适用。当执行类定义的主体时,类本身还不存在。语句(__init__函数定义和get_info(__init__)调用)发生在新的本地命名空间中;发生调用时get_info__init__是对该名称空间中函数的引用,它与类外部定义的函数没有区别。