python - 如何使用 __pycache__ 文件夹运行 Python 项目?

标签 python python-3.x compilation cpython pyc

我想使用 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 运行这个项目as fine,跟sub.py有关系:

    python main.pyc
    

    输出:

    Hi
    Bye
    
  • main.py内容:

    from subfolder import sub
    
    print('Bye')
    
  • 子.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()
    
  • 子.py内容:

    print('Hi')
    

问题:

如何使用 __pycache__ 运行此项目(在 Python3 项目之上)文件夹?

或者

如何使用 python 编译运行具有子文件夹之间关系的 Python3 项目?


[注意]:

  • 我无法使用 python compileall (Python2编译)在上面Python3项目由于asyncio方法。

  • 我的 Python 版本是 Python2.7Python3.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 版本 3.Y 运行生成的 pyc 文件是行不通的:不同的 Python 版本需要不同的 pyc 文件,这就是整点落后PEP-3147 .

关于python - 如何使用 __pycache__ 文件夹运行 Python 项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53918318/

相关文章:

python - 如何获取导致 any() 返回 True 的值?

java IntStream cannot use collect(Collectors.toList()),编译错误,为什么?

编译 SQLite 以在 Windows Mobile 上运行

python - 在预期中创建交互式选项

python - python 中的动态语句在一个实体发生变化时绘制图形

python - 为一列中的多行生成不同的随机数

compilation - : run compiled elixir binary in iex console

python - Python Bottle 服务器关闭时的 Run 方法

mysql - pip3 install mysqlclient 在 centos ec2 实例中出错

python - Glom 处理或跳过具有不同键的数据的 PathError?