Python: как гарантировать, что ваш код не будет случайно импортирован используемыми вами библиотеками? - PullRequest
0 голосов
/ 11 октября 2018

Несколько часов назад я был достаточно небрежен, чтобы назвать свой короткий сценарий как code.py.Очевидно, существует такой пакет , который используется, например, ptvsd или pdb.Это привело к тому, что мой code.py был импортирован вместо этого и вызвал кучу вложенных необработанных исключений с отсутствующим импортом при попытке отладки моего кода.Что еще более расстраивало, так это то, что traceback не показывал никаких признаков импорта моего code.py файла, поэтому я потратил довольно много времени, чтобы найти источник проблемы.

Я бы хотел избежать такогоСитуации в будущем, поэтому мой вопрос: какова лучшая практика, чтобы гарантировать, что используемые вами модули не импортируют ваш код по ошибке из-за такого конфликта имен?

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

Вы не можете полностью избежать, что кто-то может импортировать ваш модуль по ошибке.

Вы можете лучше структурировать свой код в подпакетах, переходя от «хорошо известных» к «менее известным» именам.Например, если вы разрабатываете код для определенной компании, вы можете захотеть структурировать его следующим образом:

company.country.location.department.function

Если ваш код становится более приемлемым и используемым другими, вы можете принестикод в верхнем пространстве имен, чтобы сделать его доступным в company.country.location.department.function и company.country.location.department

0 голосов
/ 11 октября 2018

Это распространенная ошибка, и на самом деле не существует надежного способа избежать этого.По крайней мере, вы можете убедиться, что все ваши модули живут в пакетах (по крайней мере, один пакет, если это небольшой проект без кода для повторного использования), чтобы вы использовали их как from mypackage import code вместо import code (также убедитесь, что вы используете либоабсолютный импорт и т. д.) и что вы всегда запускаете свой код из каталога, содержащего пакет (ы), а не из самого каталога пакета (python вставляет текущий рабочий каталог в первую позицию sys.path).

Это не предотвратит ВСЕ возможные проблемы с маскировкой имен, но должно минимизировать их.По опыту, когда вы сталкивались с подобными проблемами хотя бы один раз, вы обычно обнаруживаете симптомы очень быстро - наиболее распространенным и совершенно очевидным является то, что какой-то совершенно не связанный модуль stlib или третьей части начинает падать с помощью ImportErrors или AttributeErrors (с«модуль X не имеет атрибута Y»).На этом этапе, если вы только что добавили новый модуль в свой собственный код, скорее всего, это новый модуль, который нарушает все, так что вы можете просто переименовать его (убедитесь, что вы очищаете файлы .pyo / .pyc, если есть) и посмотрите, еслиэто решает проблему.В противном случае проверьте трассировку, чтобы выяснить, какой импорт завершился неудачно, большую часть времени вы обнаружите, что у вас есть модуль или пакет с тем же именем в вашем текущем рабочем каталоге.

0 голосов
/ 11 октября 2018

Вы можете изменить sys.path в начале вашего основного модуля, прежде чем начать импортировать другие модули:

import sys
sys.path.append(sys.path.pop(0))

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

РЕДАКТИРОВАТЬ: Для всех downvoters этот ответ на самом деле работает.

ДляНапример, выполнение code.py со следующим содержимым:

import pdb
pdb.run('print("Hello world")')

вызовет повышение:

AttributeError: module 'pdb' has no attribute 'run'

, поскольку code.py не определено run, а при выполнении code.py свместо этого следующее содержимое:

import sys
sys.path.append(sys.path.pop(0))
import pdb
pdb.run('print("Hello world")')

будет правильно исполнено pdb.run:

> <string>(1)<module>()
(Pdb)
...