【问题标题】:How to run a Python project using __pycache__ folder?如何使用 __pycache__ 文件夹运行 Python 项目?
【发布时间】:2018-12-24 23:24:37
【问题描述】:

我想使用 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__ 文件夹是手动生成的。但是我不能使用与subfolder 有关系的main.cpython-36.pyc 运行这个项目:

    cd test3/__pycache__
    python3 main.cpython-36.pyc
    

    Out(我预计会产生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 项目?


[注意]:

  • 由于asyncio 方法,我无法在上述Python3 项目中使用python compileallPython2 编译)。

  • 我的 Python(s) 版本是 Python2.7Python3.6

【问题讨论】:

    标签: python python-3.x compilation cpython pyc


    【解决方案1】:

    您可以使用以下命令在文件夹中强制执行与 Python2 中相同的 pyc 文件布局:

    python3 -m compileall -b test3
    

    -b 选项将pyc-files 的输出触发到它们的旧位置(即与 Python2 中的相同)。

    之后,您可以通过以下方式再次使用已编译的缓存:

    python3 main.pyc
    

    PEP-3147开始加载模块的方式,不可能以你想要的方式使用__pycache__文件夹中的pyc-files:如果没有*.py-file,@987654330的内容@ 从未被查找过。这是工作流程中最重要的部分:

       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 后面的整点。

    【讨论】:

      猜你喜欢
      • 2022-07-21
      • 2015-05-13
      • 1970-01-01
      • 2020-12-22
      • 2019-09-29
      • 2017-01-29
      • 2011-09-18
      • 2017-08-15
      • 2019-03-10
      相关资源
      最近更新 更多