Igo*_*ets 4 python python-import zipapp
我有一个模块,我将作为独立应用程序分发。该模块具有以下结构:
\n$ tree -L 2 ./\n./\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mymodule\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __main__.py\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 fun.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 mymodule.pyz\nRun Code Online (Sandbox Code Playgroud)\nmymodule/__main__.py包含下一行:
#!/usr/bin/env python\n\nimport argparse\nimport sys\nimport os.path\nfrom mymodule.fun import Fun\n\ndef main():\n sys.stdout.write(\'main is running\')\n Fun().run()\n\nif __name__ == \'__main__\':\n main()\nRun Code Online (Sandbox Code Playgroud)\nmymodule/fun.py包含下一行:
#!/usr/bin/env python\n\nimport sys\n\nclass Fun:\n """FUN"""\n\n def __init__(self):\n pass\n\n def run(self):\n sys.stdout.write("fun")\nRun Code Online (Sandbox Code Playgroud)\n如果我使用$ python -m mymodule输出运行模块\nmain is runningfun
但是如果我使用它创建一个独立的应用程序$ python -m zipapp -p "/usr/bin/evn python" mymodule并运行它,$ python mymodule.pyz我会收到错误
Traceback (most recent call last):\n File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/runpy.py", line 193, in _run_module_as_main\n "__main__", mod_spec)\n File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/runpy.py", line 85, in _run_code\n exec(code, run_globals)\n File "mymodule.pyz/__main__.py", line 6, in <module>\nModuleNotFoundError: No module named \'mymodule\'\nRun Code Online (Sandbox Code Playgroud)\n出什么问题了import?
UPD:\nsys.path 输出
\nTraceback (most recent call last):\n File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/runpy.py", line 193, in _run_module_as_main\n "__main__", mod_spec)\n File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/runpy.py", line 85, in _run_code\n exec(code, run_globals)\n File "mymodule.pyz/__main__.py", line 6, in <module>\nModuleNotFoundError: No module named \'mymodule\'\nRun Code Online (Sandbox Code Playgroud)\n
首先,我使用错误的命令运行应用程序,正确的是:
\n$ python mymodule\nRun Code Online (Sandbox Code Playgroud)\n要创建单文件应用程序并运行它,我需要使用:
\n$ python -m zipapp -p "/usr/bin/evn python" mymodule\n$ python mymodule.pyz\nRun Code Online (Sandbox Code Playgroud)\n要运行单元测试,我需要使用:
\n$ python -m unittest\nRun Code Online (Sandbox Code Playgroud)\n但单元测试由于错误而失败:
\n====================================================================== \nERROR: test_fun (unittest.loader._FailedTest) \n---------------------------------------------------------------------- \nImportError: Failed to import test module: test_fun \nTraceback (most recent call last): \n File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/unittest/loader.py", line 153, in loadTestsFromName \n module = __import__(module_name) \n File "/Users/igork/developer/github/python/testzipapp/tests/test_fun.py", line 2, in <module> \n from mymodule.fun import Fun \n File "/Users/igork/developer/github/python/testzipapp/mymodule/fun.py", line 8, in <module> \n from bar import Bar \nModuleNotFoundError: No module named \'bar\' \n \n \n---------------------------------------------------------------------- \nRan 1 test in 0.000s \n \nFAILED (errors=1) \nRun Code Online (Sandbox Code Playgroud)\n为了修复该错误,我在文件中添加了下一行tests/__init__.py:
====================================================================== \nERROR: test_fun (unittest.loader._FailedTest) \n---------------------------------------------------------------------- \nImportError: Failed to import test module: test_fun \nTraceback (most recent call last): \n File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/unittest/loader.py", line 153, in loadTestsFromName \n module = __import__(module_name) \n File "/Users/igork/developer/github/python/testzipapp/tests/test_fun.py", line 2, in <module> \n from mymodule.fun import Fun \n File "/Users/igork/developer/github/python/testzipapp/mymodule/fun.py", line 8, in <module> \n from bar import Bar \nModuleNotFoundError: No module named \'bar\' \n \n \n---------------------------------------------------------------------- \nRan 1 test in 0.000s \n \nFAILED (errors=1) \nRun Code Online (Sandbox Code Playgroud)\n总结一下:\n我使用的项目的结构是:
\ntestzipapp $ tree -L 2 \n. \n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 create-pyz.sh \n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mymodule \n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __main__.py \n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar.py \n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 fun.py \n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mymodule.pyz \n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tests \n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py \n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 test_fun.py \n \nRun Code Online (Sandbox Code Playgroud)\n文件tests/test_fun.py是:
import sys \nsys.path.append(\'mymodule\') \nRun Code Online (Sandbox Code Playgroud)\n文件mymodule/__main__.py 是:
testzipapp $ tree -L 2 \n. \n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 create-pyz.sh \n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mymodule \n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __main__.py \n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar.py \n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 fun.py \n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mymodule.pyz \n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tests \n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py \n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 test_fun.py \n \nRun Code Online (Sandbox Code Playgroud)\n