Проблема, с которой я сталкиваюсь чаще всего, заключается в том, что я часто хочу запустить файл __init__.py
в качестве сценария для тестирования функций, но их не следует запускать при загрузке пакета.Существует полезный обходной путь для различных путей выполнения между python <package>/__init__.py
и python -m <package>
.
$ python -m <module>
выполняет <package>/__main__.py
.__init__.py
не загружен. $ python <package>/__init__.py
просто выполняет скрипт __init__.py
как обычный скрипт.
Проблема
Когда мы хотим, чтобы __init__.py
имел предложение if __name__ == '__main__': ...
, которое использует материал из __main__.py
.Мы не можем импортировать __main__.py
, потому что он всегда будет импортировать __main__.pyc
с пути интерпретатора.( Если только … мы прибегаем к хакам импорта с абсолютным путем, которые могут вызвать много других беспорядков).
Решение Решение:)
Используйте два файла сценария для модуля __main__
:
<package>/
__init__.py
__main__.py
main.py
# __init__.py
# ...
# some code, including module methods and __all__ definitions
__all__ = ['foo', 'bar']
bar = {'key': 'value'}
def foo():
return bar
# ...
if __name__ == '__main__':
from main import main
main.main()
# __main__.py
# some code...such as:
import sys
if (len(sys.argv) > 1 and sys.argv[1].lower() == 'option1'):
from main import main()
main('option1')
elif (len(sys.argv) > 1 and sys.argv[1].lower() == 'option2'):
from main import main()
main('option2')
else:
# do something else?
print 'invalid option. please use "python -m <package> option1|option2"'
# main.py
def main(opt = None):
if opt == 'option1':
from __init__ import foo
print foo()
elif opt == 'option2':
from __init__ import bar
print bar.keys()
elif opt is None:
print 'called from __init__'
Импорт в main.py
, вероятно, не идеален в том случае, если мы запускаем из __init__.py
, поскольку мы перезагружаем их в локальную область видимости другого модуля, несмотря на то, что уже загружаем их в __init__.py
, но явная загрузка должнаИзбегайте круговой нагрузки.Если вы снова загрузите весь модуль __init__
в свой main.py
, он не будет загружен как __main__
, поэтому должен быть безопасным для круговой загрузки.