代码之家  ›  专栏  ›  技术社区  ›  Jesse Aldridge

获取已定义方法的类

  •  67
  • Jesse Aldridge  · 技术社区  · 15 年前

    如何获取在Python中定义方法的类?

    我希望打印以下示例“ __main__.FooClass

    class FooClass:
        def foo_method(self):
            print "foo"
    
    class BarClass(FooClass):
        pass
    
    bar = BarClass()
    print get_class_that_defined_method(bar.foo_method)
    
    4 回复  |  直到 12 年前
        1
  •  74
  •   Aaron Hall    10 年前
    import inspect
    
    def get_class_that_defined_method(meth):
        for cls in inspect.getmro(meth.im_class):
            if meth.__name__ in cls.__dict__: 
                return cls
        return None
    
        2
  •  9
  •   estani    12 年前

    这是一个正确的方法,它与Alex的方法一样,但不需要导入任何内容。但我不认为这是一个改进,除非有一个巨大的继承类层次结构,因为这种方法在找到定义类后立即停止,而不是将整个继承作为一个类返回 getmro 做如前所述,这是一个 非常 不太可能的情况。

    def get_class_that_defined_method(method):
        method_name = method.__name__
        if method.__self__:    
            classes = [method.__self__.__class__]
        else:
            #unbound method
            classes = [method.im_class]
        while classes:
            c = classes.pop()
            if method_name in c.__dict__:
                return c
            else:
                classes = list(c.__bases__) + classes
        return None
    

    举个例子:

    >>> class A(object):
    ...     def test(self): pass
    >>> class B(A): pass
    >>> class C(B): pass
    >>> class D(A):
    ...     def test(self): print 1
    >>> class E(D,C): pass
    
    >>> get_class_that_defined_method(A().test)
    <class '__main__.A'>
    >>> get_class_that_defined_method(A.test)
    <class '__main__.A'>
    >>> get_class_that_defined_method(B.test)
    <class '__main__.A'>
    >>> get_class_that_defined_method(C.test)
    <class '__main__.A'>
    >>> get_class_that_defined_method(D.test)
    <class '__main__.D'>
    >>> get_class_that_defined_method(E().test)
    <class '__main__.D'>
    >>> get_class_that_defined_method(E.test)
    <class '__main__.D'>
    >>> E().test()
    1
    

    Alex解决方案返回相同的结果。只要可以使用Alex方法,我就会使用它而不是这个方法。

        3
  •  7
  •   Nick Chapman    7 年前

    def get_class_that_defined_method(meth):
        return meth.im_class.__name__
    

    对于Python3,我相信这已经改变了,您需要研究 .__qualname__ .

        4
  •  6
  •   Matthew D. Scholefield    5 年前

    在Python 3中,如果需要实际的类对象,可以执行以下操作:

    import sys
    f = Foo.my_function
    vars(sys.modules[f.__module__])[f.__qualname__.split('.')[0]]  # Gets Foo object
    

    如果函数可能属于嵌套类,则需要按如下方式进行迭代:

    f = Foo.Bar.my_function
    vals = vars(sys.modules[f.__module__])
    for attr in f.__qualname__.split('.')[:-1]:
        vals = vals[attr]
    # vals is now the class Foo.Bar
    
        5
  •  1
  •   Thomas Guyot-Sionnest    8 年前

    我的解决方法其实很简单;设置方法 属性

    class A():
        def method(self):
            pass
        method._orig = None # This attribute will be gone once the method is implemented
    
        def run_method(self, *args, **kwargs):
            if hasattr(self.method, '_orig'):
                raise Exception('method not implemented')
            self.method(*args, **kwargs)
    
    class B(A):
        pass
    
    class C(B):
        def method(self):
            pass
    
    class D(C):
        pass
    
    B().run_method() # ==> Raises Exception: method not implemented
    C().run_method() # OK
    D().run_method() # OK
    

    更新:实际上是打电话 method() 从…起 run_method() (这不是精神吗?)。

    注:这个答案并不能直接回答这个问题。有两个原因,一个是想知道哪个类定义了一个方法;第一个是在调试代码中指向类(例如在异常处理中),第二个是确定该方法是否已重新实现(其中该方法是一个存根,由程序员实现)。这个答案以另一种方式解决了第二种情况。

        6
  •  1
  •   firelynx    4 年前

    Python 3

    用一种非常简单的方法解决了这个问题:

    str(bar.foo_method).split(" ", 3)[-2]

    这给

    'FooClass.foo_method'

    按点拆分以分别获取类和函数名

    推荐文章