Что-то не так с импортом модуля python в определение рутины или класса? [Дубликат]

1

Возможный дубликат:
Должны ли операторы импорта Python всегда находиться в верхней части модуля?

Недавно я ответил на вопрос SO и предоставил эту процедуру в качестве решения:

def set_fontsize(fig,fontsize):
    import matplotlib
    """
    For each text object of a figure fig, set the font size to fontsize
    """
    if not isinstance(fig,matplotlib.figure.Figure):
        raise Exception("fig is not a matplotlib.figure.Figure")

    for textobj in fig.findobj(match=matplotlib.text.Text): 
        textobj.set_fontsize(fontsize)

Я импортировал matplotlib в определение set_fontsize(fig,fontsize) потому что он не гарантировал, что кто-то, использующий эту процедуру, будет импортировать matplotlib в более глобальную область (лучшая терминология?). Тем более, что многие из примеров matplotlib вызывают подпрограммы с использованием этого импорта: import matplotlib.pyplot as plt.

Существуют ли случаи, когда мой импорт matplotlib может привести к конфликту?

Существуют ли затраты на эффективность?

Есть ли предпочтительная/более общая альтернатива тестированию, если fig является экземпляром matplotlib.figure.Figure; альтернатива, которая не требует импорта модуля?

  • 0
    @carl, этот вопрос и ответы на него в значительной степени охватывают то, что я спрашивал.
Теги:
module
import
instance

2 ответа

2

нет ничего плохого в импорте внутри функций и классов - это полезный способ обработки взаимно рекурсивного импорта (например, два файла, каждый из которых импортирует другой).

однако при проверке типа аргумента есть что-то не так. идиоматический питон не будет проверять тип рис. вместо этого просто запретите неправильное использование, где бы он ни терпел неудачу. это потому, что вы нарушаете "утиную печать" - люди не могут вызывать вашу рутину с объектами, которые "работают как" fig, даже если они этого хотят (очевидным примером является тестирование mocks; другой пример - кто-то, пишущий замену matplotlib, который имеет тот же API, но выглядит лучше или лучше).

поэтому для кода, который у вас есть, нет необходимости иметь импорт вообще. просто используйте fig.

В общем случае импорт кэшируется при первом использовании, поэтому вам, как правило, не нужно много беспокоиться об эффективности (я не говорю, что это идеальный вариант, но это то, что вам нужно профилировать, прежде чем беспокоиться).

  • 0
    спасибо за объяснение, почему бы не проверить тип аргумента. Я думаю, что мне все еще нужен импорт куда-то для вызова findobj, который должен знать matplotlib.text.Text .
  • 0
    хорошо, имеет смысл.
Показать ещё 1 комментарий
1

Там нет ничего особенно плохого в импорте внутри функции - хотя вы должны сделать это после docstring, иначе Python не увидит docstring, но ваши рассуждения не имеют никакого смысла.

Если вы импортируете на уровне модуля, а кто-то импортирует вашу функцию, функция имеет доступ ко всем вещам в своем модуле, включая импорт. Пользователям вашей функции не нужно ничего импортировать.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню