Python: заставьте lib использовать переопределенный класс - PullRequest
0 голосов
/ 04 марта 2019

представьте, что вы используете библиотеку python.Предположим, что в этой библиотеке есть один скрипт и пара классов, которые представляют интерес.Все эти классы определены в отдельных файлах.Предположим, что класс D импортируется и используется классами A, B и C несколькими способами.Точно так же класс A использует класс B, а класс B использует класс C. В сценарии используется прямое использование класса A и, следовательно, прямое и косвенное использование класса D. Теперь предположим, что вы хотите настроить D и локально определить класс D ', которыйявляется производным от класса D.

Какой самый элегантный способ заставить скрипт и другие классы (A, B, C) использовать класс D 'вместо D?

Спасибои хорошего дня!

1 Ответ

0 голосов
/ 04 марта 2019

Вы можете обезьяна пропатчить библиотеку .

# a.py
import d
class A():
    my_d = d.D()

# script.py
A.d.D = D_prime

def foo():
    a_cls = a.A() # uses A.d.D is D'

Способ, которым a.py импортирует D, имеет значение

# a.py
from d import D
class A():
    my_d = D()

# script.py
A.D = D_prime

def foo():
    a_cls = a.A() # uses A.D is D'

Другие схемы импорта могут включать похожие шаблоны,Нечто подобное может быть очень трудно исправить.

def builder():
    from d import D
    return D()

Также может быть полезно посмотреть, как библиотека mock делает это.Если это игрушка, вы могли бы использовать это напрямую.patch в частности это интересно .

@patch('A.d.D', new=D_prime)
def my_func(...):
    a = A() # a.d.D is D_prime

Исправление обезьян - это запах кода, в зависимости от юнит-теста в коде приложения это запах.Ничто из этого не является "изящным".Если вы являетесь автором библиотеки, пожалуйста, поддержите внедрение зависимостей.

Если вы храбры, вы можете вытащить некоторые из патч-декораторов во что-то, что не сфокусировано на мошенничестве.Поскольку этот шаблон существует в библиотеке unittest, его можно считать питоническим и «элегантным» с оговоркой выше.

Если вас интересует как это работает , вы модифицируететаблица символов для модуля a.Подробнее см. глобальные и местные .

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