Должен ли я использовать numpy (или pylab) в качестве среды Python, используя `from numpy import *`? - PullRequest
12 голосов
/ 21 апреля 2011

Я использую pylab (точнее numpy) во всех моих программах на python. Исключения очень редки, если таковые имеются. До сих пор я привык импортировать numpy следующим образом:

from numpy import *

Это имеет то преимущество, что выглядит так, будто numpy был частью python с самого начала. Есть ли что-то плохое в том, чтобы импортировать numpy, как это, в каждом скрипте? Я имею в виду, кроме того факта, что каждый скрипт / программа потребует немного больше памяти и займет больше времени для загрузки.

Я думаю, что всегда приходиться писать numpy или даже np перед каждым вызовом функции, который исходит от numpy (например, np.zeros(3)), утомительно, потому что мне нужно знать, какая функция происходит от numpy, а какая нет. Меня не волнует, что функция нулей происходит от numpy или python, я просто хочу / нужно ее использовать.

Какая запись лучше по вашему мнению?

Ответы [ 5 ]

19 голосов
/ 21 апреля 2011
  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])
    

    Полный набор коллизий имен можно найти таким образом (благодаря @Джо Кингтон и @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']
    
  2. Это может привести к очень запутанным ошибкам, поскольку кто-то, кто тестирует или использует ваш код в интерпретаторе Python без from numpy import *, может увидетьповедение совершенно иное, чем у вас.

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

    Порядок импорта может также иметь значение, если оба модуля переопределят одно и то же имя.

    И трудно понять, откуда берутся функции и значения.

  4. Хотя можно использовать from numpy import * и по-прежнему получать доступ к встроенным функциям Python, это неудобно:

    from numpy import *
    any([[False]])
    __builtins__.any([[False]])
    

    и менее читабельно, чем:

    import numpy as np
    np.any([[False]])
    any([[False]])
    
  5. Как говорит дзен Python,

    Пространства имен - отличная идея- давайте использовать больше из них!

Мой совет - никогда не использовать from module import * в любом сценарии, точка.

11 голосов
/ 22 апреля 2011

Просто чтобы пояснить, что говорили другие люди, numpy - это особенно плохой модуль для использования import * с.

pylab предназначен для интерактивного использования, и это хорошотам.Никто не хочет набирать pylab.zeros снова и снова в оболочке, когда они могут просто набрать zeros.Однако, как только вы начинаете писать код, все меняется.Вы набираете его один раз , и он может остаться навсегда, и другие люди (например, вы год спустя), вероятно, будут пытаться выяснить, какого черта вы делали.

В дополнение к тому, что @unutbu уже говорил о переопределении встроенных в Python sum, float int и т. Д., И к тому, что все говорили о незнании, откуда взялась функция, numpy и pylabочень большие пространства имен.

numpy имеет 566 функций, переменных, классов и т. д. в своем пространстве имен.Это много!pylab имеет 930 !(А с pylab они приходят из нескольких разных модулей.)

Конечно, достаточно легко угадать, откуда zeros или ones или array, но как насчет source илиDataSource или lib.utils?(все они будут в вашем локальном пространстве имен, если вы сделаете from numpy import *

Если у вас есть проект немного большего размера, есть большая вероятность, что вы будете иметь локальную переменную или переменную в другом файлеэто имя похоже на что-то в большом модуле, таком как numpy. Внезапно, вы начинаете беспокоиться о том, что именно вы называете!

В качестве другого примера, как бы вы различалиФункция 1040 * fft и numpy fft модуль ?

В зависимости от того, выполняете ли вы

from numpy import *
from pylab import *

или:

from pylab import *
from numpy import *

fft - это полностью другое с полностью другим поведением! (Т.е. попытка вызвать fft во втором случае вызовет ошибку.)

В общем, вы всегда должны избегать from module import *, но это особенно плохая идея в случае numpy, scipy и др., Потому что они такие большие пространства имен.

Конечно, все это было сказано, если вы просто суетитесь в раковине, пытаясьo быстро получить график некоторых данных, прежде чем приступить к действию с ним, а затем использовать pylab.Вот для чего это.Только не пишите что-то, что кто-то может попытаться прочитать позже в будущем!

</rant>

2 голосов
/ 23 апреля 2011

Давайте разберемся с другой стороны, я получаю ваш код для отладки и вижу, что вы звоните:

zeros(5)

утомительно проверять ваш источник, чтобы убедиться, что это np.нулями или вы переопределили его где-то еще, и так как pylab имеет 930 имен, это может произойти легко.

2 голосов
/ 21 апреля 2011

Я бы сказал, что преимущество - знать, откуда поступает каждый вызов функции. Это дает вам больший контроль над тем, что находится в вашем пространстве имен, и позволяет избежать всевозможных потенциальных конфликтов, которые будут болезненными для отладки. Если вы думаете, import numpy as np утомительно, просто подождите, пока у вас не появится какой-нибудь сторонний модуль, который переопределяет имя функции, и вам нужно отыскать какое-то таинственное поведение, которого вы не ожидали.

2 голосов
/ 21 апреля 2011

Это не является существенной проблемой, если numpy - единственный модуль, который вы импортируете таким образом. Никогда НИКОГДА не импортируйте какие-либо другие модули, подобные этим, в свои скрипты (если только этот модуль не был написан вами, и вы все о нем знаете, и он достаточно мал. Например, иногда вы разбиваете модуль на два файла, чтобы лучше разделить их на части).

Общее правило: Читаемость кода не пострадает значительно, если таким образом импортировать широко используемые модули (например, numpy). Но никогда не импортируйте больше одного.

Мое правило: Я НИКОГДА не делаю такого рода импорт. Я всегда делаю что-то вроде «import numpy as np», если это будет использоваться много раз.

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