Рекомендується не використовувати import *
в Python.
Хтось може, будь ласка, поділитися причиною цього, щоб я міг уникнути цього наступного разу?
import *
не працює для мене в першу чергу в Python 2 або 3.
Рекомендується не використовувати import *
в Python.
Хтось може, будь ласка, поділитися причиною цього, щоб я міг уникнути цього наступного разу?
import *
не працює для мене в першу чергу в Python 2 або 3.
Відповіді:
Оскільки він містить багато речей у вашій області імен (може затінити якийсь інший об'єкт із попереднього імпорту, і ви про нього не дізнаєтесь).
Тому що ви точно не знаєте, що імпортується, і не можете легко знайти, з якого модуля було імпортовано певну річ (читабельність).
Тому що ви не можете використовувати класні інструменти, як, наприклад, pyflakes
статичне виявлення помилок у коді.
numpy.any
тіні, any
коли вони це роблять, from numpy import *
або "корисний" інструмент робить це для них.
import *
робить замовлення з import
заяв значних ... навіть для стандартних модулів бібліотеки , які зазвичай не піклуються про порядок ввезення . Щось таке невинне, як import
буквене позначення ваших заяв, може зламати ваш сценарій, коли колишня жертва війни за імпорт стане єдиною жертвою. (Навіть якщо ваш сценарій працює зараз і ніколи не змінюється, він може раптом вийти з ладу десь пізніше, якщо імпортований модуль введе нове ім'я, яке замінить одне, на яке ви покладалися.)
use strict
(JavaScript var
). З іншого боку, Python, звичайно, не є типовим (він насправді сильно набраний). У будь-якому випадку, навіть якби ви мали рацію, це все одно суперечить дзену Питона, про який йдеться у цій відповіді.
Ви не переходите **locals()
до функцій, чи не так?
Оскільки Python відсутня оператор «включити», іself
параметр є явним, і Scoping правила досить прості, це, як правило , дуже легко вказати пальцем на змінну і сказати , де цей об'єкт приходить від - без читання інших модулів і без будь - яких IDE (які так чи інакше обмежені способом самоаналізу, адже мова є дуже динамічною).
The import *
перервах все це.
Також він має конкретну можливість приховування клопів.
import os, sys, foo, sqlalchemy, mystuff
from bar import *
Тепер, якщо в панельному модулі є який-небудь з атрибутів " os
", " mystuff
" і т. Д. ..., вони замінять явно імпортовані і, можливо, вказують на дуже різні речі. Визначення __all__
в рядку часто є розумним - це говорить про те, що імпліцитно імпортуватиметься, - але все ж важко простежити, звідки беруться об'єкти, не читаючи та розбираючи модуль бару та слідкуючи за його імпортом. Мережа import *
- це перше, що я фіксую, коли приймаю право власності на проект.
Не розумійте мене неправильно: якби import *
зникли безвісти, я б плакала, щоб це було. Але використовувати його потрібно обережно. Гарним випадком використання є надання інтерфейсу фасаду через інший модуль. Аналогічно, використання умовних заяв про імпорт або імпорту всередині просторів імен функції / класу вимагає трохи дисципліни.
Я думаю, що в середніх і великих проектах, або малих з кількома учасниками, необхідний мінімум гігієни з точки зору статичного аналізу - запуску принаймні піфляк або, ще краще, правильно налаштованого пілінта - щоб зловити кілька помилок раніше вони бувають.
Звичайно, оскільки це пітон - сміливо порушуйте правила та досліджуйте, - але будьте обережні до проектів, які можуть зрости вдесятеро, якщо у вихідному коді відсутня дисципліна, це буде проблемою.
execfile()
. На щастя, він рідко використовується і проходить у 3.x.
**vars()
включення глобальних даних, якщо викликана функція знаходиться в іншому файлі? : P
Це тому, що ви забруднюєте простір імен. Ви будете імпортувати всі функції та класи у власному просторі імен, що може зіткнутися з функціями, які ви самі визначаєте.
Крім того, я думаю, що використання кваліфікованого імені є більш зрозумілим для технічного обслуговування; ви бачите в самому рядку коду, звідки походить функція, так що ви можете перевірити документи набагато легше.
У модулі foo:
def myFunc():
print 1
У вашому коді:
from foo import *
def doThis():
myFunc() # Which myFunc is called?
def myFunc():
print 2
http://docs.python.org/tutorial/modules.html
Зауважте, що загалом практика імпорту
*
з модуля чи пакету нахмурена, оскільки це часто спричинює погано читабельний код .
Скажімо, у вас є наступний код у модулі під назвою foo:
import ElementTree as etree
а потім у власному модулі у вас є:
from lxml import etree
from foo import *
Тепер у вас є складний для налагодження модуль, схожий на те, що в ньому є етрія lxml, але натомість замість нього використовується ElementTree.
Це все хороші відповіді. Я хочу додати, що при навчанні нових людей кодувати в Python, мати справу з import *
дуже складно. Навіть якщо ви чи вони не написали код, це все одно камінь спотикання.
Я вчу дітей (приблизно 8 років) програмувати в Python, щоб маніпулювати Minecraft. Мені подобається надавати їм корисне середовище кодування для роботи ( Atom Editor ) та навчати розробці, керованій REPL (через bpython ). В Atom я вважаю, що підказки / завершення працюють так само ефективно, як і bpython. На щастя, на відміну від деяких інших інструментів статистичного аналізу, Atom не обдурить import *
.
Однак давайте взяти цей приклад ... У цій обгортці вони from local_module import *
купують модулі, включаючи цей список блоків . Давайте ігноруємо ризик зіткнень простору імен. Тим самим from mcpi.block import *
вони складають весь цей список незрозумілих типів блоків, те, що вам потрібно переглянути, щоб знати, що є в наявності. Якби вони замість цього використовувались from mcpi import block
, ви можете набрати, walls = block.
а потім з'явиться список автозаповнення.
Зрозуміли дійсні моменти, які тут ставлять люди. Однак у мене є один аргумент, що іноді "імпорт зірок" не завжди може бути поганою практикою:
const.py
:
import const
, то для кожної константи я маю позначати це як const.SOMETHING
, що, мабуть, не найзручніший спосіб.from const import SOMETHING_A, SOMETHING_B ...
, то, очевидно, це занадто багатослівно і перемагає мета структуризації.from const import *
кращий вибір може бути.Це дуже BAD практика з двох причин:
Для пункту 1 : Давайте подивимось приклад цього:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
Тут, побачивши код, ніхто не здобуде уявлення щодо того, з якого модуля b
, c
і d
насправді належить.
З іншого боку, якщо ви робите це так:
# v v will know that these are from module1
from module1 import b, c # way 1
import module2 # way 2
a = b + c - module2.d
# ^ will know it is from module2
Вам набагато чистіше, а також нова людина, яка приєднається до вашої команди, матиме кращу ідею.
Для пункту 2 : Нехай говорять обидва module1
і module2
мають змінну як b
. Коли я роблю:
from module1 import *
from module2 import *
print b # will print the value from module2
Тут module1
втрачається значення з . Буде важко налагодити, чому код не працює, навіть якщо b
він задекларований, module1
і я написав код, очікуючи використання мого кодуmodule1.b
Якщо у різних модулях є однакові змінні, і ви не хочете імпортувати весь модуль, ви навіть можете:
from module1 import b as mod1b
from module2 import b as mod2b
Як тест я створив модуль test.py з двома функціями A і B, які відповідно друкують "A 1" і "B 1". Після імпорту test.py за допомогою:
import test
. . . Я можу запустити 2 функції як test.A () і test.B (), а "test" відображається як модуль у просторі імен, тому, якщо я редагую test.py, я можу перезавантажити його за допомогою:
import importlib
importlib.reload(test)
Але якщо я виконую наступне:
from test import *
у просторі імен немає посилання на "тест", тому немає можливості перезавантажити його після редагування (наскільки я можу сказати), що є проблемою в інтерактивному сеансі. Беручи до уваги будь-яке з наступного:
import test
import test as tt
додасть "test" або "tt" (відповідно) як імена модулів у просторі імен, що дозволить повторно завантажити.
Якщо я:
from test import *
імена "A" і "B" відображаються в просторі імен як функції . Якщо я редагую test.py і повторюю вищезгадану команду, змінені версії функцій не завантажуються.
І наступна команда видає повідомлення про помилку.
importlib.reload(test) # Error - name 'test' is not defined
Якщо хтось знає, як перезавантажити модуль, завантажений "з імпорту модуля *", будь ласка, опублікуйте. В іншому випадку це буде ще однією причиною уникати форми:
from module import *
Як пропонується в документах, ви (майже) ніколи не повинні використовувати import *
у виробничому коді.
Хоча імпорт *
з модуля поганий, імпорт * з пакету ще гірший. За замовчуванням from package import *
імпортується будь-які назви, визначені пакетом __init__.py
, включаючи будь-які підмодулі пакета, завантажені попереднімиimport
заявами.
Однак якщо __init__.py
код пакета визначає список з назвою __all__
, він вважається списком імен підмодулів, які слід імпортувати, коли from package import *
виникає.
Розглянемо цей приклад (припустимо, що в ньому не __all__
визначено sound/effects/__init__.py
):
# anywhere in the code before import *
import sound.effects.echo
import sound.effects.surround
# in your module
from sound.effects import *
Останній оператор буде імпортувати модулі echo
та surround
модулі в поточну область імен (можливо, переосмислюючи попередні визначення), оскільки вони визначені в sound.effects
пакеті при виконанні import
оператора.