如何使用 __pycache__ 文件夹 运行 一个 Python 项目?
How to run a Python project using __pycache__ folder?
我想 运行 使用 Python 编译(.pyc
或 __pycache__
)的 Pythonic 项目。为了在 Python2 中做到这一点,我没有任何问题。
这是 Python2 项目中的一个简化示例:
项目树:
test2
├── main.py
└── subfolder
├── __init__.py
└── sub.py
编译:
python -m compileall test2
编译后的项目树:
test2
├── main.py
├── main.pyc
└── subfolder
├── __init__.py
├── __init__.pyc
├── sub.py
└── sub.pyc
可以看到,手动生成了几个.pyc
。现在我可以运行这个项目使用main.pyc
一样好,这与sub.py
:
有关系
python main.pyc
输出:
Hi
Bye
main.py内容:
from subfolder import sub
print('Bye')
sub.py内容:
print('Hi')
现在我想在 Python3 项目中重试此行为。
这是一个简化的 asyncio
(在 Python3 中可用)项目:
项目树:
test3
├── main.py
└── subfolder
├── __init__.py
└── sub.py
编译:
python3 -m compileall test3
编译后的项目树:
test3
├── main.py
├── __pycache__
│ └── main.cpython-36.pyc
└── subfolder
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-36.pyc
│ └── sub.cpython-36.pyc
└── sub.py
如您所见,手动生成了 __pycache__
个文件夹。但是我不能 运行 这个项目使用 main.cpython-36.pyc
与 subfolder
:
有关系
cd test3/__pycache__
python3 main.cpython-36.pyc
输出(我预计会产生 Hi Bye
消息):
Traceback (most recent call last):
File "test3/main.py", line 2, in <module>
ModuleNotFoundError: No module named 'subfolder'
main.py内容:
import asyncio
from subfolder import sub
async def myCoroutine():
print("Bye")
def main():
loop = asyncio.get_event_loop()
loop.run_until_complete(myCoroutine())
loop.close()
main()
sub.py内容:
print('Hi')
问题:
如何使用 __pycache__
文件夹 运行 这个项目(在 Python3 项目之上)?
或
如何使用 python 编译 运行 一个 Python3 项目与子文件夹之间的关系?
[注意]:
我无法在上面的Python3
项目中使用python compileall
(Python2编译) asyncio
方法。
我的Python(s)版本是Python2.7和Python3.6
您可以在文件夹中强制执行与 Python2 中相同的 pyc 文件布局,方法是:
python3 -m compileall -b test3
选项 -b
触发 pyc
文件输出到它们的遗留位置(即与 Python2 相同)。
之后您可以通过以下方式再次使用已编译的缓存:
python3 main.pyc
自 PEP-3147 以来模块的加载方式无法按您想要的方式使用 __pycache__
文件夹中的 pyc 文件:如果没有 *.py
-文件,永远不会查找 __pycache__
的内容。这是工作流程中最重要的部分:
import foo
|
|
-- > [foo.py exists?] --- NO ----> [foo.pyc exists?] -- NO --> [ImportError]
| |
| YES
YES |--> [load foo.pyc]
|
|-> [look up in __pycache__]
这意味着,只有当可以找到相应的 *.py
文件时,才会查找来自 __pycache__
的文件。
显然,使用 Python 版本 3.X 以这种方式构建 python 脚本并尝试 运行 使用另一个 Python 生成的 pyc 文件版本 3.Y 将不起作用:不同的 Python 版本需要不同的 pyc 文件,这就是 PEP-3147.
背后的重点
我想 运行 使用 Python 编译(.pyc
或 __pycache__
)的 Pythonic 项目。为了在 Python2 中做到这一点,我没有任何问题。
这是 Python2 项目中的一个简化示例:
项目树:
test2 ├── main.py └── subfolder ├── __init__.py └── sub.py
编译:
python -m compileall test2
编译后的项目树:
test2 ├── main.py ├── main.pyc └── subfolder ├── __init__.py ├── __init__.pyc ├── sub.py └── sub.pyc
可以看到,手动生成了几个
有关系.pyc
。现在我可以运行这个项目使用main.pyc
一样好,这与sub.py
:python main.pyc
输出:
Hi Bye
main.py内容:
from subfolder import sub print('Bye')
sub.py内容:
print('Hi')
现在我想在 Python3 项目中重试此行为。
这是一个简化的 asyncio
(在 Python3 中可用)项目:
项目树:
test3 ├── main.py └── subfolder ├── __init__.py └── sub.py
编译:
python3 -m compileall test3
编译后的项目树:
test3 ├── main.py ├── __pycache__ │ └── main.cpython-36.pyc └── subfolder ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-36.pyc │ └── sub.cpython-36.pyc └── sub.py
如您所见,手动生成了
有关系__pycache__
个文件夹。但是我不能 运行 这个项目使用main.cpython-36.pyc
与subfolder
:cd test3/__pycache__ python3 main.cpython-36.pyc
输出(我预计会产生
Hi Bye
消息):Traceback (most recent call last): File "test3/main.py", line 2, in <module> ModuleNotFoundError: No module named 'subfolder'
main.py内容:
import asyncio from subfolder import sub async def myCoroutine(): print("Bye") def main(): loop = asyncio.get_event_loop() loop.run_until_complete(myCoroutine()) loop.close() main()
sub.py内容:
print('Hi')
问题:
如何使用 __pycache__
文件夹 运行 这个项目(在 Python3 项目之上)?
或
如何使用 python 编译 运行 一个 Python3 项目与子文件夹之间的关系?
[注意]:
我无法在上面的
Python3
项目中使用python compileall
(Python2编译)asyncio
方法。我的Python(s)版本是Python2.7和Python3.6
您可以在文件夹中强制执行与 Python2 中相同的 pyc 文件布局,方法是:
python3 -m compileall -b test3
选项 -b
触发 pyc
文件输出到它们的遗留位置(即与 Python2 相同)。
之后您可以通过以下方式再次使用已编译的缓存:
python3 main.pyc
自 PEP-3147 以来模块的加载方式无法按您想要的方式使用 __pycache__
文件夹中的 pyc 文件:如果没有 *.py
-文件,永远不会查找 __pycache__
的内容。这是工作流程中最重要的部分:
import foo
|
|
-- > [foo.py exists?] --- NO ----> [foo.pyc exists?] -- NO --> [ImportError]
| |
| YES
YES |--> [load foo.pyc]
|
|-> [look up in __pycache__]
这意味着,只有当可以找到相应的 *.py
文件时,才会查找来自 __pycache__
的文件。
显然,使用 Python 版本 3.X 以这种方式构建 python 脚本并尝试 运行 使用另一个 Python 生成的 pyc 文件版本 3.Y 将不起作用:不同的 Python 版本需要不同的 pyc 文件,这就是 PEP-3147.
背后的重点