Как запустить проект Python, используя папку __pycache__? - PullRequest
0 голосов
/ 25 декабря 2018

Я хочу запустить проект Pythonic, используя компиляцию Python (.pyc или __pycache__).Чтобы сделать это в 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
    

    Out:

    Hi
    Bye
    
  • main.py content:

    from subfolder import sub
    
    print('Bye')
    
  • sub.py content:

    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
    

    Out (я ожидал, что выдало сообщение Hi Bye):

    Traceback (most recent call last):
      File "test3/main.py", line 2, in <module>
    ModuleNotFoundError: No module named 'subfolder'
    
  • main.py content:

    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 content:

    print('Hi')
    

Вопрос:

Как мне запустить этот проект (выше Python3 проект), используя папку __pycache__?

Или

Как запустить Python3 проект с отношением между подпапками с использованием компиляции Python?


[ NOTE ]:

  • Я не могу использоватьpython compileall ( Python2 compile) в вышеупомянутом Python3 проекте из-за метода asyncio.

  • Моя версия Python (ов) Python2.7 и Python3,6

1 Ответ

0 голосов
/ 27 декабря 2018

Вы можете принудительно использовать тот же макет pyc-файлов в папках, что и в Python2, используя:

python3 -m compileall -b test3

Опция -b запускает вывод pyc -файлы в их прежние места (то есть в Python2).

После этого вы можете снова использовать скомпилированный кеш через:

python3 main.pyc

Способ загрузки модулей с тех пор PEP-3147 , невозможно использовать pyc-файлы из папки __pycache__ так, как вы собираетесь: если файла *.py нет, содержимое __pycache__ никогда не просматривается.вверх.Вот самая важная часть рабочего процесса:

   import foo
     |
     |
     -- >  [foo.py exists?]  --- NO ----> [foo.pyc exists?]  -- NO --> [ImportError] 
            |                                     |
            |                                    YES
           YES                                    |--> [load foo.pyc]
            |
            |-> [look up in __pycache__]

Это означает, что файлы из __pycache__ ищутся только тогда, когда может быть найден соответствующий *.py -файл.

...