【问题标题】:How to inspect a method without instance? [duplicate]如何检查没有实例的方法? [复制]
【发布时间】:2016-04-09 09:26:48
【问题描述】:

我需要:

  • 接收方法作为参数(直接从类中,无实例)
  • 创建实例
  • 从实例执行上述方法

问题是,我怎样才能可靠地将类从方法中取出?我尝试在 inspect 模块中研究一些东西,但由于没有实例,它认为该方法是 function 而不是 method

这是我正在尝试做的一些示例:

def execute_method(method):
    cls = get_class_from_method(method)
    obj = cls()
    getattr(obj, method.__name__)()


def get_class_from_method(method):
    pass # how?


execute_method(HelloView.say_hello)

【问题讨论】:

    标签: python


    【解决方案1】:

    Python 2 方法对象有一个 im_class 属性引用它们绑定到的实例的类:

    cls = method.im_class
    

    对于一个未绑定的方法,在 Python 3 中,你会很不走运(函数返回完全不变,没有引用类)。 Python 2 返回一个未绑定的方法类型,其 im_class 属性仍然存在:

    >>> class Foo(object):
    ...     def bar(self): pass
    ...
    >>> Foo.bar.im_class
    <class '__main__.Foo'>
    

    在 Python 3 中,您的选择更加有限并且容易出错。您可以查看函数的 __qualname__ 属性,并从中推断出类 可能 在全局命名空间中绑定到的内容:

    >>> class Foo:
    ...     def bar(self): pass
    ...
    >>> Foo.bar
    <function Foo.bar at 0x10e97b268>
    >>> Foo.bar.__qualname__
    'Foo.bar'
    >>> Foo.bar.__qualname__.rpartition('.')[0]
    'Foo'
    >>> Foo.bar.__globals__.get(Foo.bar.__qualname__.rpartition('.')[0])
    <class '__main__.Foo'>
    

    但是,如果类是在函数中创建的(因此是本地的),或者类被类装饰器替换或只是在全局命名空间中重命名,则上述技巧充其量是行不通的,最坏的情况是给你一个完全不同的对象,你不知道是不是这样。

    【讨论】:

    • 不是绑定方法。
    • @hugo_leonardo:更新到实际工作,对此感到抱歉。
    • 哦。好的(:〜我希望python 3有办法。
    • @hugo_leonardo:没有。您可以尝试解释 __qualname__ 属性并在相同的全局变量中查找父类。但这并不能保证有效,因为该类可能是在本地命名空间中创建的,或者已经包装在类装饰器中,或者不再作为具有该名称的全局存在。
    • 我猜你是对的。刚刚发现这是一个重复的问题:stackoverflow.com/questions/3589311/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多