태그 보관물: python-2.6

python-2.6

메서드를 정의한 클래스 가져 오기 수 있습니까? 다음 예제에서 ” __main__.FooClass”을 ( 를)

파이썬에서 메서드를 정의한 클래스를 어떻게 얻을 수 있습니까?

다음 예제에서 ” __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)



답변

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


답변

내가 요점을 놓치고 있다는 것을 지적 해 주신 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

Alex 솔루션은 동일한 결과를 반환합니다. Alex 접근 방식을 사용할 수있는 한이 방법 대신 사용합니다.


답변

나는 왜 아무도 이것을 제기하지 않았는지 또는 지옥처럼 느릴 때 상위 답변에 50 개의 upvotes가있는 이유를 모르겠지만 다음을 수행 할 수도 있습니다.

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

파이썬 3의 경우 이것이 변경되었다고 생각하며 .__qualname__.


답변

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


답변

나는 다소 비슷한 일을 시작했다. 기본적으로 기본 클래스의 메서드가 하위 클래스에 구현되었는지 여부를 확인하는 것이 었습니다. 내가 원래했던 방식으로 밝혀 졌는데 중간 클래스가 실제로 메서드를 구현하고있을 때 감지 할 수 없었습니다.

내 해결 방법은 실제로 매우 간단했습니다. 메소드 속성을 설정하고 나중에 그 존재를 테스트합니다. 다음은 전체를 단순화 한 것입니다.

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()수정되지 않은 모든 인수를 메서드에 전달합니다.

추신 :이 답변은 질문에 직접 답하지 않습니다. IMHO 메서드를 정의한 클래스를 알고 싶은 두 가지 이유가 있습니다. 첫 번째는 디버그 코드 (예 : 예외 처리)에서 클래스를 가리키는 손가락이고, 두 번째는 메서드가 다시 구현되었는지 확인하는 것입니다 (여기서 메서드는 프로그래머가 구현할 스텁). 이 답변은 두 번째 경우를 다른 방식으로 해결합니다.


답변

파이썬 3

매우 간단한 방법으로 해결했습니다.

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

이것은 준다

'FooClass.foo_method'

점으로 분할하여 클래스와 함수 이름을 개별적으로 가져옵니다.


답변