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

时间:2018-12-24 23:24:37

标签: 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运行该项目,该项目与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 项目?


[注意]:

  • 由于有python compileall方法,因此无法在上述Python3项目中使用asyncio Python2 编译)。

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

1 个答案:

答案 0 :(得分:2)

您可以通过以下方式在文件夹中强制使用与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__]

这意味着,只有在找到相应的__pycache__文件时,才会查找*.py中的文件。