[英]What is the correct way to import modules for standalone app created using `python -m zipapp`?
我有一個將作為獨立應用程序分發的模塊。 該模塊具有以下結構:
$ tree -L 2 ./
./
├── mymodule
│ ├── __main__.py
│ ├── fun.py
└── mymodule.pyz
mymodule/__main__.py
包含下一行:
#!/usr/bin/env python
import argparse
import sys
import os.path
from mymodule.fun import Fun
def main():
sys.stdout.write('main is running')
Fun().run()
if __name__ == '__main__':
main()
mymodule/fun.py
包含下一行:
#!/usr/bin/env python
import sys
class Fun:
"""FUN"""
def __init__(self):
pass
def run(self):
sys.stdout.write("fun")
如果我使用$ python -m mymodule
運行模塊,輸出是main is runningfun
但是如果我使用$ python -m zipapp -p "/usr/bin/evn python" mymodule
創建一個獨立的應用程序並運行它$ python mymodule.pyz
我得到錯誤
Traceback (most recent call last):
File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "mymodule.pyz/__main__.py", line 6, in <module>
ModuleNotFoundError: No module named 'mymodule'
import
什么問題?
UPD:sys.path 輸出
$ python -m mymodule
['', '/Users/igork/.pyenv/versions/3.6.4/lib/python36.zip', '/Users/igork/.pyenv/versions/3.6.4/lib/python3.6', '/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/lib-dynload', '/Users/igork/.local/lib/python3.6/site-packages', '/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/site-packages']
$ python mymodule.pyz
['mymodule.pyz', '/Users/igork/.pyenv/versions/3.6.4/lib/python36.zip', '/Users/igork/.pyenv/versions/3.6.4/lib/python3.6', '/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/lib-dynload', '/Users/igork/.local/lib/python3.6/site-packages', '/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/site-packages']
首先,我使用錯誤的命令運行應用程序,正確的是:
$ python mymodule
要創建單文件應用程序並運行它,我需要使用:
$ python -m zipapp -p "/usr/bin/evn python" mymodule
$ python mymodule.pyz
要運行單元測試,我需要使用:
$ python -m unittest
但是單元測試由於錯誤而失敗:
======================================================================
ERROR: test_fun (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_fun
Traceback (most recent call last):
File "/Users/igork/.pyenv/versions/3.6.4/lib/python3.6/unittest/loader.py", line 153, in loadTestsFromName
module = __import__(module_name)
File "/Users/igork/developer/github/python/testzipapp/tests/test_fun.py", line 2, in <module>
from mymodule.fun import Fun
File "/Users/igork/developer/github/python/testzipapp/mymodule/fun.py", line 8, in <module>
from bar import Bar
ModuleNotFoundError: No module named 'bar'
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
為了修復錯誤,我在tests/__init__.py
文件中添加了下一行:
import sys
sys.path.append('mymodule')
總結一下:我使用的項目結構是:
testzipapp $ tree -L 2
.
├── create-pyz.sh
├── mymodule
│ ├── __main__.py
│ ├── bar.py
│ ├── fun.py
├── mymodule.pyz
└── tests
├── __init__.py
├── test_fun.py
文件tests/test_fun.py
是:
import unittest
from mymodule.fun import Fun
class TestFunImports(unittest.TestCase):
def test_fun_run(self):
s = Fun()
s.run()
self.assertEqual(2+2,4)
文件mymodule/__main__.py
是:
#!/usr/bin/env python
import sys
from fun import Fun
def main():
sys.stdout.write('main is running ')
Fun().run()
if __name__ == '__main__':
main()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.