最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

pyinstaller打包找不到文件的問題解決

 更新時間:2020年04月15日 10:14:37   作者:PurePeace  
這篇文章主要介紹了pyinstaller打包找不到文件的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1、將python程序打包成單文件(使用 -F 參數(shù))后,嘗試運行外部文件卻提示找不到的問題

當你將python程序打包成單文件(使用 -F 參數(shù))后,運行程序,它實際上是先將exe內(nèi)的資源文件解壓到臨時文件夾,然后再運行的,所以會導致這種問題

比如,當你在程序里面調(diào)用一個外部exe時,但卻提示找不到該exe文件。

例子(這里我用win32api去隱式運行外部exe文件):

import win32api
win32api.ShellExecute(0, 'open', 'nginx.exe', '', '', 0)

首先,你需要將這個外部的exe文件添加進pyinstaller的打包里。

有兩種方法:

1、直接用參數(shù)添加:

--add-data "nginx.exe;."

完整命令:pyinstaller -F main.py --add-data "nginx.exe;."

2、在spec文件添加:

每次執(zhí)行pyinstaller打包命令后會生成spec文件,打開它
在里面找到data=[] 列表,添加元素,變成了:datas=[('nginx.exe', '.')]
然后用spec打包:pyinstaller main.spec
我解釋一下這個點“.”是什么意思:

由于使用單文件打包出來的exe會先解壓再運行,所以點“.” 其實表示你打包的這個exe文件運行解壓的完整路徑

如:C:\...\temp(臨時文件夾)\asdqwezxc(你程序運行時自動解壓到的目錄)

  • 所以這個nginx.exe 被打包后,會解壓到 C:\...\temp\asdqwezxc\nginx.exe
  • 如果把點“.”改為test,就會解壓到 C:\...\temp\asdqwezxc\test\nginx.exe
  • 以此類推

好,現(xiàn)在nginx.exe已被打包。然后要注意一個問題:

打包出來的exe在運行時,它的工作路徑和它解壓到的路徑,是不一樣的!

你可以測試一下:

import os
print(os.getcwd())

可以發(fā)現(xiàn),打印出來的工作路徑并不是它運行時解壓到的路徑!
而是這個打包出來的exe,它本身所存在的路徑!

問題來了:

諸如open('xxx.txt')這些操作文件的函數(shù),一般首先都是在工作路徑查找你所指定的文件的。

所以,當我們直接這樣執(zhí)行已打包的外部文件時,程序會報找不到文件!所以請使用它的解壓路徑。

下面提供一個函數(shù),可以很方便的獲取到解壓路徑:

import os, sys
def base_path(path):
  if getattr(sys, 'frozen', None):
    basedir = sys._MEIPASS
  else:
    basedir = os.path.dirname(__file__)
  return os.path.join(basedir, path)

print(base_path(''))
print(base_path('test\gg.exe'))

第一句打印會顯示完整的解壓路徑:

C:\...\temp\asdqwezxc\

第二句打印是這樣的:

C:\...\temp\asdqwezxc\test\gg.exe

所以當我們在調(diào)用已打包的外部文件時,應該先使用os.chdir()將工作路徑改為解壓路徑:

再進行操作,就不會報文件找不到了

os.chdir(base_path(''))
win32api.ShellExecute(0, 'open', 'nginx.exe', '', '', 0)

不過要注意的是,如果你要寫出文件到程序所在的目錄(非解壓目錄),那么你得把工作目錄改回來,否則文件會被寫出到解壓路徑(臨時文件夾)。

稍微封裝一下就好了:

import os, sys

def base_path(path):
  if getattr(sys, 'frozen', None):
    basedir = sys._MEIPASS
  else:
    basedir = os.path.dirname(__file__)
  return os.path.join(basedir, path)

tmd = base_path('') # 這是解壓路徑
cwd = os.getcwd() # 這是程序的所在路徑

# 當需要調(diào)用打包的外部文件時
os.chdir(tmd) # 先把工作路徑變成解壓路徑
do() # 執(zhí)行你要干的事情

# 當需要寫出文件到程序所在目錄時
os.chdir(cwd) # 把工作路徑切換回來
do() # 執(zhí)行你要干的事情

2、當你使用cython將py文件編譯成pyd文件后使用pyinstaller打包,提示找不到模塊的問題
直接使用pyinstaller打包py文件是很容易導致源碼被反編譯的

所以在打包的時候最好將py文件編譯成pyd文件,這樣可以很大程度上防止反編譯。

為什么呢?因為pyd文件的來歷是這樣的:

py文件 → c文件 → pyd文件
所以直接反編譯pyd只能得到上一步cython生成的c文件,而無法得到我們的py源文件。

如何打包pyd成文件請看這篇文章:http://m.fzitv.net/article/184725.htm
接下來回到我們的問題。

解決方法很簡單,請看:

比如說,我有一個文件main.py,引入了位于同級目錄下的test.py模塊

# main.py:就像這樣直接引入
import test

現(xiàn)在我將test.py 編譯成pyd文件,生成了:test.cp37-win_amd64.pyd

這個pyd文件名除了我們原本的文件名test,還會帶上編譯環(huán)境的名稱,這個環(huán)境后綴名我們可以不用管 ,因為python引入模塊還是很智能的(會自動引入.pyd文件,因為它的優(yōu)先級高于.py文件)。

這么智能,但是為什么我用pyinstaller打包時就提示找不到文件?
其實我們需要在打包時--hidden-import這些模塊

1、直接添加

在打包時添加--hidden-import test即可
完整命令:pyinstaller -F --hidden-import test

2、使用spec文件

同樣的,運行一次pyinstaller打包命令后會生成spec文件,打開它
找到hiddenimports=[],添加test模塊,變成了:hiddenimports=['test']
很簡單對吧?
而且除了我們自己寫的一些py模塊,其它模塊在打包時可能也會提示找不到,都可以用這個方法解決。

3、打包成單文件時(使用-F參數(shù)),運行時要求管理員權(quán)限的參數(shù)--uac-admin無效的問題
請看我的這篇文章:pyinstaller打包單文件時–uac-admin選項不起作用怎么辦

本質(zhì)上大概也是因為找不到文件。

4、無控制臺打包(使用-w參數(shù)),運行時彈框提示Failed to execute script的問題
請看我的這篇文章:pyinstaller打包成無控制臺程序時運行出錯,與popen沖突的解決方法

這個問題一般是程序內(nèi)有輸入導致的,這個輸入可以是input(),也可以是其它的一些stdin操作(如os.popen實際上會造成輸入請求)

本質(zhì)上就是:使用-w參數(shù)(無控制臺)打包時程序里不要請求輸入

當然,實在要用輸入,又不想要控制臺怎么辦?很簡單,把控制臺隱藏了就行!

下列兩個方法,試試看:

import ctypes
def hideConsole():
  """
  Hides the console window in GUI mode. Necessary for frozen application, because
  this application support both, command line processing AND GUI mode and theirfor
  cannot be run via pythonw.exe.
  """

  whnd = ctypes.windll.kernel32.GetConsoleWindow()
  if whnd != 0:
    ctypes.windll.user32.ShowWindow(whnd, 0)
    # if you wanted to close the handles...
    #ctypes.windll.kernel32.CloseHandle(whnd)

def showConsole():
  """Unhides console window"""
  whnd = ctypes.windll.kernel32.GetConsoleWindow()
  if whnd != 0:
    ctypes.windll.user32.ShowWindow(whnd, 1)

暫時就這么多呃,都是本人在打包過程中實際上遇到過的問題和經(jīng)驗。?;究捎?br />

到此這篇關(guān)于pyinstaller打包找不到文件的問題解決的文章就介紹到這了,更多相關(guān)pyinstaller打包找不到文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python將print輸出的信息保留到日志文件中

    python將print輸出的信息保留到日志文件中

    這篇文章主要介紹了python將print輸出的信息保留到日志文件中,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • python的sys.path模塊路徑添加方式

    python的sys.path模塊路徑添加方式

    這篇文章主要介紹了python的sys.path模塊路徑添加方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • python 高效去重復 支持GB級別大文件的示例代碼

    python 高效去重復 支持GB級別大文件的示例代碼

    今天小編就為大家分享一篇python 高效去重復 支持GB級別大文件的示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Python批量安裝卸載1000個apk的方法

    Python批量安裝卸載1000個apk的方法

    這篇文章主要介紹了Python批量安裝卸載1000個apk的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • Python3正則匹配re.split,re.finditer及re.findall函數(shù)用法詳解

    Python3正則匹配re.split,re.finditer及re.findall函數(shù)用法詳解

    這篇文章主要介紹了Python3正則匹配re.split,re.finditer及re.findall函數(shù)用法,結(jié)合實例形式詳細分析了正則匹配re.split,re.finditer及re.findall函數(shù)的概念、參數(shù)、用法及操作注意事項,需要的朋友可以參考下
    2018-06-06
  • Python實現(xiàn)語音合成功能詳解

    Python實現(xiàn)語音合成功能詳解

    這篇文章主要為大家介紹了一個通過Python制作的小工具,可以實現(xiàn)語音識別以及文字轉(zhuǎn)語音的功能,文中的實現(xiàn)步驟講解詳細,感興趣的可以動手試一試
    2022-01-01
  • PyQtGraph在pyqt中的應用及安裝過程

    PyQtGraph在pyqt中的應用及安裝過程

    這篇文章主要介紹了PyQtGraph在pyqt中的應用,文中給大家介紹了pyqtgraph的主要用途及PyQtGraph的安裝過程,需要的朋友可以參考下
    2019-08-08
  • 使用優(yōu)化器來提升Python程序的執(zhí)行效率的教程

    使用優(yōu)化器來提升Python程序的執(zhí)行效率的教程

    這篇文章主要介紹了使用優(yōu)化器來提升Python程序的執(zhí)行效率的教程,包括編寫計時器和使用內(nèi)建的優(yōu)化器等,需要的朋友可以參考下
    2015-04-04
  • Python數(shù)據(jù)庫格式化輸出文檔的思路與方法

    Python數(shù)據(jù)庫格式化輸出文檔的思路與方法

    這篇文章主要給大家介紹了關(guān)于Python數(shù)據(jù)庫格式化輸出文檔的思路與方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • 利用Python讀取Excel表內(nèi)容的詳細過程

    利用Python讀取Excel表內(nèi)容的詳細過程

    python有多種方式可以去讀取excel文檔的內(nèi)容,下面這篇文章主要給大家介紹了利用Python讀取Excel表內(nèi)容的詳細過程,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-10-10

最新評論

集安市| 内乡县| 抚远县| 雅江县| 东乡| 鹤壁市| 无极县| 扬州市| 阳新县| 精河县| 七台河市| 泗阳县| 正镶白旗| 集安市| 桃园市| 武定县| 临颍县| 宜兴市| 泽库县| 长顺县| 丽江市| 睢宁县| 平安县| 巩义市| 和顺县| 博白县| 华容县| 丰台区| 芦山县| 阿拉善右旗| 建阳市| 普兰县| 苏州市| 彭州市| 元氏县| 黄冈市| 依安县| 南江县| 滦南县| 河南省| 田东县|