6

如果变量引用函数或类方法,我如何找出它是哪一个并获取类类型,以防它是类方法,特别是当类仍如给定示例中那样声明时。

例如。

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)

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

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

4

3 回答 3

13

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

>>> type(bar)
<type 'function'>
>>> type(Foo.__init__)
<type 'instancemethod'>

或者

>>> import types
>>> isinstance(bar, types.FunctionType)
True
>>> isinstance(bar, types.UnboundMethodType)
True

这就是你在if声明中这样做的方式。

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

>>> Foo.__init__.im_class
__main__.Foo
于 2009-03-30T00:29:51.447 回答
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

输出(CPython,IronPython):

<function __init__ at ...>
<unbound method Foo.__init__>
<bound method Foo.__init__ of <__main__.Foo object at ...>>
<function bar at ...>

输出(Jython):

<function __init__ 1>
<unbound method Foo.__init__>
<method Foo.__init__ of Foo instance 2>
<function bar 3>
于 2009-03-30T00:42:17.203 回答
4

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

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

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

于 2009-03-30T07:20:29.383 回答