Обезьяно-патчующий класс с унаследованными классами в Python - PullRequest
0 голосов
/ 06 марта 2020

После прочтения ответов на вопрос о классах исправлений обезьян в Python Я попытался применить рекомендованное решение к следующему случаю.

Представьте, что у нас есть модуль a.py

class A(object):
    def foo(self):
        print(1)

class AA(A):
    pass

, и давайте попробуем сделать это следующим образом. Это работает, когда мы используем класс патчей обезьяны A:

>>> import a
>>> class B(object):
...     def foo(self):
...             print(3)
... 
>>> a.A = B
>>> x = a.A()
>>> x.foo()
3

Но если мы попробуем унаследованный класс, он не будет исправлен:

>>> y = a.AA()
>>> y.foo()
1

Есть ли способ обезьяны исправить класс со всеми его унаследованными классами?

РЕДАКТИРОВАТЬ

На данный момент лучшее решение для меня выглядит следующим образом:

>>> class AB(B, a.AA):
...     pass
... 
>>> a.AA = AB
>>> x = a.AA()
>>> x.foo()
3

Любой сложная структура a.AA будет унаследована, и единственным отличием между AB и a.AA будет метод foo(). Таким образом, мы не изменяем никакие внутренние атрибуты класса (например, __base__ или __dict__). Единственный оставшийся недостаток - это то, что нам нужно сделать это для каждого из унаследованных классов.

Это лучший способ сделать это?

1 Ответ

1 голос
/ 07 марта 2020

Вам необходимо явно перезаписать кортеж базовых классов в a.AA, хотя я не рекомендую изменять классы, подобные этой.

>>> import a
>>> class B:
...   def foo(self):
...     print(2)
...
>>> a.AA.__bases__ = (B,)
>>> a.AA().foo()
2

Это также будет отражено в a.A.__subclasses__() (хотя я Я не совсем уверен относительно как , который работает; тот факт, что это метод, предполагает, что он каким-то образом вычисляет это во время выполнения, а не просто возвращает значение, которое было изменено первоначальным определением AA) .

Появляется , что базовые классы в операторе class просто запоминаются, а не используются , пока некоторые операции не потребуются (например, во время поиска атрибута) , Могут быть и другие тонкие угловые случаи, которые обрабатываются не так гладко: caveat programmator .

...