Получение текущего класса в вызове метода - PullRequest
2 голосов
/ 03 октября 2010
class A:
    def x ( self ):
        print( self.__class__ )

class B ( A ):
    pass

b = B()
b.x()

В описанной выше ситуации есть ли способ для метода x получить ссылку на класс A вместо B? Конечно, просто писать print( A ) недопустимо, так как я хочу добавить некоторые функциональные возможности с декоратором, которому нужен класс A (и, поскольку я не могу передать A непосредственно декоратору, так как класс не существует еще в этот момент).

Ответы [ 2 ]

4 голосов
/ 03 октября 2010

Если у вас не задействованы super -вызовы (или, в более общем случае, подклассы, которые переопределяют x и обращаются напрямую к A.x(self) как часть реализации их переопределения), ища первый элемент в type(self).mro(), который имеет x атрибут будет работать -

next(c for c in type(self).mro() if hasattr(c, 'x'))

Если вам нужно покрыть вызовы super, это будет сложнее - если только вы не узнаете, что никакой супер -класс A не определяет атрибут x (и, конечно, легче узнать о ваших суперклассах, чем о ваших подклассах, хотя множественное наследование усложняет его ;-) в этом случае вам нужен только последний соответствующий элемент mro вместо первого.

2 голосов
/ 03 октября 2010

Вы можете использовать искажение имени, чтобы связать класс, в котором определен метод, с методом:

def set_defining_class(cls):
    setattr(cls, '_%s__defining_class' % (cls.__name__,), cls)
    return cls

@set_defining_class
class A(object):
    def x (self):
        print(self.__defining_class)

@set_defining_class
class B ( A ):
    pass


b = B()
b.x()

Сделано здесь с декоратором класса, но вы можете сделать это вручную или в метаклассе..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...