PyInstaller入門(二)——__import__ ()無法被識別的問題和spec文件的使用

pyinstaller無法識別問題

爲了找出你的python文件的所有依賴項,pyinstaller會查看你的python腳本中所有的import聲明 ,找到所有導入的模塊,直到擁有了你的python腳本執行所需的所有模塊的完整列表。
PyInstaller可以識別出python包常用的”egg”格式,所以,如果你的腳本是從一個”egg”中導入一個模塊,那麼pyinstaller將會把egg和它的依賴項一併添加進來。
一些常用的GUI包目前也都被pyinstaller支持,例如:Qt,WxPython, TkInter, Django等等。
或許你的一些腳本中使用了import()等格式的導入,這是pyinstaller無法識別的包導入格式,或者在運行時操作sys.path的值等等。這些都是pyinstaller無法直接識別的。需要你手動做一些其他的工作幫助pyinstaller識別這些內容。

  • 通過向pyinstaller添加需要的文件或者路徑
  • 編輯 你的文件名.spec文件來添加pystaller無法自動識別的內容(後續將詳細介紹)
  • 寫hook文件來提醒pyinstaller那些隱藏的import

使用命令行添加未識別的import模塊

pyinstaller –hidder-import=ModuleName hello.py

spec文件的使用

當你執行

pyinstaller options.. myscript.py

的時候,pyinstaller做的第一件事情就是生成一個myscript.spec文件,這個文件在–specpath=文件夾下,默認情況下是在當前路徑下。
spec file如下:

block_cipher = None
a = Analysis(['minimal.py'],
     pathex=['/Developer/PItests/minimal'],
     binaries=None,
     datas=None,
     hiddenimports=[],
     hookspath=None,
     runtime_hooks=None,
     excludes=None,
     cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
     cipher=block_cipher)
exe = EXE(pyz,... )
coll = COLLECT(...)

包含了你的腳本名字以及你給pyinstaller命令的各種選項。多數情況下,使用命令行是足夠的,但以下幾種情況需要你修改spec file文件:

  • 想要將數據文件捆綁到應用程序中
  • 想要包含run-time庫(.dll或.so文件)
  • 想要添加python的run-time選項
  • 想要創建具有合併公共模塊的多程序包
    首先,使用下面的命令創建一個spec file:

pyi-makespec options name.py [other scripts …]
在spec file中,你會看到四個類: Analysis, PYZ, EXE 和 COLLECT。

  • Analysis使用列表列出所有輸入的python腳本。它會分析所有的導入包和依賴項,並將結果賦給輸出對象(例子中的a)。a是一個列表的形式,包含如下幾項:
    scripts:所有輸入python腳本;
    pure:輸入腳本中命名的純python模塊;
    binaries:腳本中需要的非python模塊;
    datas:應用包含的非二進制文件。

  • pyz:該類的一個實例將包含a.pure中的所有python模塊;

  • EXE: 該類的一個實例將生成可執行文件;
  • COLLECT:該類的一個實例將創建一個包含除上述內容以外的其他所有部分的輸出文件;

    向Analysis中添加內容

    添加數據文件

例如添加一個src文件夾中存在的README.txt文件

a = Analysis(...
     datas=[ ('src/README.txt', '.') ],
     ...
     )

例如:添加某個文件夾下的所有.mps文件:

a = Analysis(...
     datas= [ ('/mygame/sfx/*.mp3', 'sfx' ) ],
     ...
     )

這樣,所有/mygame/sfx/文件夾下的mp3文件都會被添加到你的應用中。
如果你要添加一系列的數據文件,使用下面的方式可以增加可讀性:

added_files = [
         ( '/mygame/sfx/*.mp3', 'sfx' ),
         ( 'src/README.txt', '.' )
         ]
    a = Analysis(...
         datas = added_files,
         ...
         )

使用某個模塊中的數據文件

如果你想要添加的某個數據文件是來源於某個python模塊。
例如:你的文件中有一個叫做helpmod的模塊,它包含以下幾個部分:

helpmod:
init.py
helpmod.py
help_data.txt

事實上,使用命令行的pyinstaller進行壓縮,像help_data.txt文件是不會被包含進去的,因此應當修改spec file文件如下:

a = Analysis(...
     datas= [ ('helpmod/help_data.txt', 'helpmod' ) ],
     ...
     )

另外一種方法:使用標準庫函數 pkgutil.get_data( )在你的helpmod.py中:

import pkgutil
help_bin = pkgutil.get_data( 'helpmod', 'help_data.txt' )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章