Python 获取已定义方法的类

Python 获取已定义方法的类,python,python-2.6,python-datamodel,Python,Python 2.6,Python Datamodel,如何获取在Python中定义方法的类 我希望下面的示例打印“\uuuuu main\uuuuu.FooClass”: 感谢Sr2222指出我没有抓住重点 这是一个正确的方法,它与Alex的方法一样,但不需要导入任何内容。不过,我不认为这是一种改进,除非存在大量继承类的层次结构,因为一旦找到定义类,这种方法就会停止,而不是像getmro那样返回整个继承。如前所述,这是一种极不可能的情况 def get_class_that_defined_method(method): method_na

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

我希望下面的示例打印“
\uuuuu main\uuuuu.FooClass
”:


感谢Sr2222指出我没有抓住重点

这是一个正确的方法,它与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
>>A类(对象):
...     def测试(自身):通过
>>>B(A)级:及格
>>>丙(乙)级:及格
>>>D(A)类:
...     def测试(自身):打印1
>>>E级(D、C):及格
>>>获取\u定义的\u类\u方法(A().test)
>>>获取\u定义的\u类\u方法(A.test)
>>>获取\u定义的\u类\u方法(B.test)
>>>获取\u定义的\u类\u方法(C.test)
>>>获取\u定义的\u类\u方法(D.test)
>>>获取\u定义的\u类\u方法(E().test)
>>>获取定义的类方法(E.test)
>>>E().test()
1.

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

感谢Sr2222指出我没有抓住要点

这是一个正确的方法,它与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
>>A类(对象):
...     def测试(自身):通过
>>>B(A)级:及格
>>>丙(乙)级:及格
>>>D(A)类:
...     def测试(自身):打印1
>>>E级(D、C):及格
>>>获取\u定义的\u类\u方法(A().test)
>>>获取\u定义的\u类\u方法(A.test)
>>>获取\u定义的\u类\u方法(B.test)
>>>获取\u定义的\u类\u方法(C.test)
>>>获取\u定义的\u类\u方法(D.test)
>>>获取\u定义的\u类\u方法(E().test)
>>>获取定义的类方法(E.test)
>>>E().test()
1.

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

我开始做一些类似的事情,基本上是检查基类中的方法是否在子类中实现。事实证明,按照我最初的方式,我无法检测到中间类何时实际实现了该方法

我的解决方法其实很简单;设置方法属性并稍后测试其存在性。这是整个事情的简化:

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
更新:从
run\u method()
(这不是精神吗?)实际调用
method()
,并让它将所有未修改的参数传递给该方法


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

我开始做一些类似的事情,基本上是检查基类中的方法是否在子类中实现。事实证明,按照我最初的方式,我无法检测到中间类何时实际实现了该方法

我的解决方法其实很简单;设置方法属性并稍后测试其存在性。这是整个事情的简化:

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
更新:从
run\u method()
(这不是精神吗?)实际调用
method()
,并让它将所有未修改的参数传递给该方法


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

我不知道为什么从来没有人提出过这个问题,也不知道为什么在速度非常慢的情况下,排名靠前的答案有50票赞成票,但你也可以做以下事情:

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

对于Python3,我相信这已经改变了,您需要研究一下
。\uuuu qualname\uuu

,我不知道为什么从来没有人提出过这个问题,或者为什么在速度非常慢的情况下,排名靠前的答案会有50票赞成票,但您也可以做以下事情:

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

对于Python3,我相信这一点已经改变,您需要查看Python3中的
。\uuuuQualname\uuuu

,如果您需要实际的类对象,您可以执行以下操作:

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

在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
Python 3 用一种非常简单的方法解决了这个问题:

str(bar.foo_方法).split(“,3)[-2]

这给

'FooClass.foo\u方法'

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

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

str(bar.foo_方法).split(“,3)[-2]

这给

'FooClass.foo\u方法'


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

您使用的是什么版本的Python?在2.2版本之前,您可以使用im_类,但它被更改为显示绑定的self对象的类型。很高兴知道。但是我使用的是2.6。您使用的是什么版本的Python?在2.2之前,你可以使用im_类b