簡體   English   中英

修改 Python/PIP 導入失敗時自動安裝模塊

[英]Modify Python/PIP to automatically install modules when failed to import

有沒有辦法將 python/pip 修改為,每當運行時導入失敗,它會嘗試從 pip 安裝模塊(同名)然后導入模塊?

我會說這比僅僅拋出錯誤更好。 如果從 pip 加載模塊后發生任何問題,那么它也會拋出錯誤,類似於當我注意到我無法導入某些內容時,嘗試pip install然后出現完全相同的錯誤消息

我知道我們可以使用requirements.txt來捆綁一個包,但我是從“客戶端”(運行腳本的人)而不是“提供者”(提供腳本的人)的角度談論; 也就是說,作為客戶,我希望能夠導入任何腳本並自動解決依賴關系。

我知道這可能會導致麻煩,但是每當我看到 ImportError 時,我都會嘗試pip install模塊。 只有在 pip 安裝后模塊無法工作時,“我才會問更多問題”。

我想到了類似這個片段的東西,它會“內置”到 python 進程中:

def getDirectoryOfInterpreter(p):
    return "someway to return the directory"

try:
    import somemodule
except ImportError:
    os.system(getDirectoryOfInterpreter('THIS_INTERPRETER_BINARY') + ' pip install ' + "MODULE_NAME")
    import somemodule

使用virtualenv時,您可以使用pipimport執行此操作。 如果您有適當的權限來編寫必要的目錄(至少是site-packages ,但您的導入可能有一些命令, pip會嘗試將其放在 PATH 中的某個位置),它可能適用於系統 python。 由於無論如何始終使用virtualenvs進行自己的開發是一種很好的做法,因此我從未嘗試過將pipimport與系統python一起使用。

您需要手動將 pipimport 導入您的 virtualenv:

virtualenv venv
source venv/bin/activate
pip install pipimport

然后創建一個文件autopipimport.py ,您首先在任何模塊中導入該文件:

# import and install pipimport
import pipimport
pipimport.install()

現在在任何其他.py文件中,您可以執行以下操作:

import autopipimport
import some.package.installable.by.pip

我曾經嘗試(出於好奇自動)將兩條與 pipimport 相關的行添加到venv/lib/python2.7/site.py以自動“加載”,但那是在鏈的早期並且不起作用。

pipimport只會嘗試使用pip安裝特定模塊一次,將有關已嘗試內容的信息存儲在.pipimport-ignore文件中(應該在venv下,除非它不可寫)。

這是我為自己的好奇心所做的事情。

是的,這不安全地使用非首選函數在后台調用具有任意用戶輸入的 shell。 請不要將此代碼用於生產。

import os

Libraries_Installed = False

def Pip_Install(library):
    """Locate pip.exe on system and install library.
    Be sure to sanitize input to prevent RCE."""
    global Lib_Installed

    if os.path.isfile('C:\\Python27\\Scripts\\pip.exe'):
        print '[!] c:\Python27\Scripts\pip.exe => pip'
        stream = os.popen('C:\Python27\Scripts\pip.exe install %s' % library)
        Result = stream.read()

        if 'Successfully installed' in str(Result):
            print '\n\n[+] Successfully installed %s' % library
            Lib_Installed = True

        elif 'FAIL' in str(Result).upper() or 'FAILED' in str(Result).upper() \
        or 'FAILURE' in str(Result).upper():
            print '[!] Unable to install %d' % library
            print '[!] Please manually run the pip installer'
            print '[!] try: C:\Python27\Scripts\pip.exe install %s' % library

    elif os.path.isfile('D:\\Python27\\Scripts\\pip.exe'):
        stream = os.popen('D:\Python27\Scripts\pip.exe install %s' % library)
        Result = stream.read()

        if 'Successfully installed' in str(Result):
            print '\n\n[+] Successfully installed %s' % library
            Lib_Installed = True

        elif 'FAIL' in str(Result).upper() or 'FAILED' in str(Result).upper() \
        or 'FAILURE' in str(Result).upper():
            print '[!] Unable to install %d' % library
            print '[!] Please manually run the pip installer'
            print '[!] try: C:\Python27\Scripts\pip.exe install %s' % library

# Python library that may need to be installed
try:
    import Tkinter
    import tkFileDialog
except:
    print '[!] Error importing Tkinter ... Trying pip installer'
    Pip_Install('tkinter')

if Lib_Installed == True:
    print '\n[!] The following Python libraries were installed automatically:'
    for library in Libs:
        print str(library)
    Q = raw_input('''\n[!] Please exit the program and run a new instance.
[!] Enter [Y] to continue anyways''')
    if Q.upper()[0] == 'Y':
        pass
    else:
        exit()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM