Импорт модулей в Python - лучшая практика

Я новичок в Python, так как хочу расширить навыки, которые я изучил, используя R. В R я имею тенденцию загружать кучу библиотек, иногда приводя к конфликтам имен функций.

Что лучше всего подходит для Python. Я видел некоторые конкретные варианты, которые я не вижу разницы между

import pandas, from pandas import * и from pandas import DataFrame

В чем разница между первыми двумя, и я должен просто импортировать то, что мне нужно. Кроме того, что будет худшими последствиями для тех, кто делает небольшие программы для обработки данных и вычисления простой статистики.

UPDATE

Я нашел это отличное руководство. Это объясняет все.

Ответ 1

import pandas импортирует модуль pandas в пространстве имен pandas, поэтому вам нужно будет вызвать объекты в pandas с помощью pandas.foo.

from pandas import * импортирует все объекты из модуля pandas в текущее пространство имен, поэтому вы вызываете объекты в pandas, используя только foo. Имейте в виду, что это может иметь необъяснимые последствия, если между вашим текущим пространством имен и пространством имен pandas существуют конфликты между именами.

from pandas import DataFrame является таким же, как указано выше, но только импортирует DataFrame (вместо всего) в ваше текущее пространство имен.

По моему мнению, первая, как правило, самая лучшая практика, так как она поддерживает различные модули, прекрасно разделенные в вашем коде.

Ответ 2

Недостаток каждой формы

При чтении кода других людей (и эти люди используют очень разные стили импорта), я заметил следующие проблемы с каждый из стилей:

import modulewithaverylongname будет загромождать код дальше вниз с длинным именем модуля (например, concurrent.futures или django.contrib.auth.backends) и уменьшением читаемости в этих местах.

from module import * не дает мне возможности синтаксически видеть, что, например, classA и classB поступают из того же модуля и имеют много общего друг с другом. Это делает чтение кода жестким. (Это имя из такого импорта возможно, теневые имена из более раннего импорта являются наименьшей частью этой проблемы.)

from module import classA, classB, functionC, constantD, functionE перегружает мою кратковременную память слишком большим количеством имен что я мысленно должен назначить module, чтобы координируйте код.

import modulewithaverylongname as mwvln иногда недостаточно Мнемонический для меня.

Подходящий компромисс

Основываясь на приведенных выше наблюдениях, я разработал следующее стиль в моем собственном коде:

import module является предпочтительным стилем, если имя модуля короткое как, например, большинство пакетов в стандартной библиотеке. Это также предпочтительный стиль, если мне нужно использовать имена из модуля в только два или три места в моем собственном модуле; ( "Показатели удобочитаемости" ).

import longername as ln является предпочтительным стилем почти в каждом другой случай. Например, я мог бы import django.contrib.auth.backends as dj_abe. По определению вышеприведенного критерия 1 аббревиатура будет использоваться часто и поэтому достаточно легко запомнить.

Только эти два стиля полностью питоничны в соответствии с "Явное правило лучше, чем неявное." .

from module import xx по-прежнему встречается иногда в моем коде. Я использую его в тех случаях, когда даже формат as выглядит преувеличенным, наиболее известным примером является from datetime import datetime.

Ответ 3

В целом лучше делать явные импорт. Как в:

import pandas
frame = pandas.DataFrame()

Или:

from pandas import DataFrame
frame = DataFrame()

Другой вариант в Python, когда у вас конфликтующие имена, является import x как y:

from pandas import DataFrame as PDataFrame
from bears import DataFrame as BDataFrame
frame1 = PDataFrame()
frame2 = BDataFrame()

Ответ 4

Вот несколько рекомендаций из Руководство по стилю PEP8.

  • Импорт обычно должен быть в отдельных строках, например:

    Yes: import os
         import sys
    
    No:  import sys, os
    

    но это нормально

    from subprocess import Popen, PIPE
    
  • Импорт всегда помещается в верхнюю часть файла сразу после комментариев и док-строк модуля, а также перед глобалями и константами модуля.

    • Импорт должен быть сгруппирован в следующем порядке:
      • импорт стандартной библиотеки
      • Связанный импорт третьей стороны
      • импорт локальных приложений/библиотек
    • Вы должны поместить пустую строку между каждой группой импорта.
  • Рекомендуется абсолютный импорт
    Они более читабельны и облегчают отладку, предоставляя улучшенные сообщения об ошибках, если вы испортили систему импорта.

    import mypkg.sibling
    from mypkg import sibling
    from mypkg.sibling import example
    

    или явно относительный импорт

    from . import sibling
    from .sibling import example
    
  • Имплицитный относительный импорт никогда не должен использоваться и удален в Python 3.

    No:  from ..grand_parent_package import uncle_package
    
  • Следует избегать импорта подстановочных знаков (from <module> import *), поскольку они неясны, какие имена присутствуют в пространстве имен, запутывая как читателей, так и множество автоматизированных инструментов.

    /li >

Некоторые рекомендации о lazy imports из советы по повышению производительности питона.

Накладные расходы на импорт

Операторы импорта

могут выполняться практически в любом месте. Часто бывает полезно разместить их внутри функций, чтобы ограничить их видимость и/или уменьшить начальное время запуска. Хотя интерпретатор Python оптимизирован, чтобы не импортировать один и тот же модуль несколько раз, повторное выполнение оператора импорта может серьезно повлиять на производительность в некоторых обстоятельствах.

приведенный ниже сценарий, описанный на странице,

>>> def doit1():
... import string
... string.lower('Python')
...
>>> import string
>>> def doit2():
... string.lower('Python')
...
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import doit1', stmt='doit1()')
>>> t.timeit()
11.479144930839539
>>> t = timeit.Timer(setup='from __main__ import doit2', stmt='doit2()')
>>> t.timeit()
4.6661689281463623

Ответ 5

from A import B

по существу равен следующим трем утверждениям

import A
B = A.B
del A

Что это, вот и все.

Ответ 6

Все они подходят в разных контекстах (вот почему они все доступны). Там нет глубокого руководящего принципа, кроме родовых утверждений материнства в ясности, ремонтопригодности и простоты. Некоторые примеры из моего собственного кода:

  • import sys, os, re, itertools избегает конфликтов имен и предоставляет очень сжатый способ импорта нескольких стандартных модулей.
  • from math import * позволяет писать sin(x) вместо math.sin(x) в математическом коде. Это становится немного рискованным, когда я также импортирую numpy, который удваивается на некоторых из них, но это меня не слишком беспокоит, так как в любом случае они, как правило, одинаковы. Кроме того, я склонен следить за документацией numpy - import numpy as np, что полностью оборачивает проблему.
  • Я одобряю from PIL import Image, ImageDraw только потому, что способ, которым документация PIL представляет свои примеры.