Должен ли я использовать numpy (или pylab) в качестве среды python, используя `from numpy import *`?
Я использую pylab (более конкретно numpy) во всех моих программах python. Исключения очень редки, если они есть. До сих пор я привык импортировать numpy следующим образом:
from numpy import *
Это имеет то преимущество, что он выглядел так, как будто numpy был частью python с самого начала. Есть ли что-то плохое в факте импорта numpy, как это, в каждом script? Я имею в виду, кроме того, что для каждой программы script/потребуется немного больше памяти и потребуется больше времени для загрузки.
Мне всегда нужно писать numpy или даже np, прежде чем каждый вызов функции, который приходит из numpy (например, np.zeros(3)
), утомительно, потому что он требует, чтобы я знал, какая функция исходит из numpy, а какая нет. Мне все равно, что функция zeros исходит из numpy или python, я просто хочу/должен ее использовать.
Какая запись лучше в соответствии с вами?
Ответы
Ответ 1
-
Использование from numpy import *
изменяет поведение any
, all
и
sum
. Например,
any([[False]])
# True
all([[True, False], [False, False]])
# True
sum([[1,2],[3,4]], 1)
# TypeError: unsupported operand type(s) for +: 'int' and 'list'
Если вы используете from numpy import *
, то значения совершенно разные:
from numpy import *
any([[False]])
# False
all([[True, False], [False, False]])
# False
sum([[1,2],[3,4]], 1)
array([3, 7])
Полный набор столкновений имен можно найти таким образом (благодаря @Joe Kington и @jolvi
для указания этого):
import numpy as np
np_locals = set(np.__all__)
builtins = set(dir(__builtins__))
print([name for name in np_locals.intersection(builtins) if not name.startswith('__')])
# ['any', 'all', 'sum']
-
Это может привести к очень запутывающим ошибкам, поскольку кто-то тестирует или использует ваши
код в интерпретаторе Python без from numpy import *
может видеть полностью
по-разному, чем вы.
-
Использование нескольких импортных форм формы from module import *
может
проблема с еще большим количеством столкновений такого рода. Если вы пресекаете эту дурную привычку в
бутон, вам никогда не придется беспокоиться об этом (потенциально путающем) ошибке.
Порядок импорта также может иметь значение, если оба модуля переопределяют одно и то же имя.
И это заставляет понять, откуда берутся функции и значения.
-
Хотя можно использовать from numpy import *
и по-прежнему получать доступ к встроенным Python, это неудобно:
from numpy import *
any([[False]])
__builtins__.any([[False]])
и менее читаемым, чем:
import numpy as np
np.any([[False]])
any([[False]])
-
Как говорит Дзен Питона,
Пространства имен - отличная идея - давайте использовать их больше!
Мой совет: никогда не использовать from module import *
в любом script, периоде.
Ответ 2
Чтобы уточнить, что говорили другие люди, numpy - особенно плохой модуль для использования import *
с.
pylab
предназначен для интерактивного использования, и это прекрасно. Никто не хочет набирать pylab.zeros
снова и снова в оболочке, когда они могут просто набрать zeros
. Однако, как только вы начинаете писать код, все меняется. Вы печатаете его один раз, и он остается потенциально навсегда, а другие люди (например, сами в год по дороге), вероятно, будут пытаться выяснить, что вы делаете.
В дополнение к тому, что уже сказал @unutbu об переопределении python builtin sum
, float
int
и т.д., и о том, что все говорили о неведении, откуда появилась функция, numpy
и pylab
очень большие пространства имен.
numpy
имеет 566 функций, переменных, классов и т.д. внутри своего пространства имен. Это много! pylab
имеет 930! (И с pylab они исходят из нескольких разных модулей.)
Конечно, достаточно легко угадать, где zeros
или ones
или array
, но как насчет source
или DataSource
или lib.utils
? (все они будут находиться в вашем локальном пространстве имен, если вы выполните from numpy import *
Если у вас есть еще немного более крупный проект, у вас будет хорошая вероятность, что у вас будет локальная переменная или переменная в другом файле, который похож на что-то в большом модуле, таком как numpy
. Внезапно вы начинаете больше заботиться о том, что именно вы звоните!
В качестве другого примера, как бы вы отличали функцию pylab
fft
и модуль numpy
fft
?
В зависимости от того, выполняете ли вы
from numpy import *
from pylab import *
или
from pylab import *
from numpy import *
fft
- совершенно другая вещь с совершенно другим поведением! (т.е. попытка вызова fft
во втором случае вызовет ошибку.)
В общем, вы всегда должны избегать from module import *
, но это особенно плохая идея в случае numpy
, scipy
, et. и др. потому что они такие большие пространства имен.
Конечно, все, что было сказано, если вы просто путешествуете в оболочке, пытаясь быстро получить сюжет некоторых данных, прежде чем переходить к тому, чтобы что-то делать с ним, тогда обязательно используйте pylab
. Что это там для. Просто не пишите что-то таким, что каждый может попытаться прочитать позже по дороге!
</rant>
Ответ 3
это не является существенной проблемой, если numpy является единственным модулем, который вы импортируете как это. Никогда не импортируйте какие-либо другие модули, подобные этому в ваших сценариях (если только этот модуль не был написан вами, и вы знаете все об этом, и он достаточно мал. Например, иногда вы разбиваете модуль на два файла, чтобы вы могли лучше разделять их).
Общее правило: ваша читаемость кода не будет сильно зависеть от импорта широко используемых модулей (таких как numpy) таким образом. Но никогда не импортируйте больше одного.
Мое правило: Я НИКОГДА не выполняю такой импорт. Я всегда делаю что-то вроде "import numpy as np", если он будет использоваться много.
Ответ 4
Я бы сказал, что это преимущество, чтобы знать, откуда происходит каждый вызов функции. Это дает вам больший контроль над тем, что находится в вашем пространстве имен, и позволяет избежать любых возможных конфликтов, которые могут быть причиной отладки. Если вы считаете, что import numpy as np
утомительно, просто подождите, пока у вас не будет стороннего модуля, который переопределит имя функции, и вам придется отслеживать некоторые таинственные действия, которые вы не ожидали.
Ответ 5
Позвольте заняться с другой стороны, я получаю ваш код для отладки, и я вижу, что вы вызываете:
zeros(5)
вам нужно заглянуть вокруг вашего источника, чтобы узнать, является ли это np.zeros или вы переопределили его где-то еще, а так как pylab имеет 930 имен, это может произойти легко.