2011-05-25 18 views
22

मैं लिखने में सक्षम होना चाहते हैं:मैं स्वचालित रूप से लापता पायथन मॉड्यूल कैसे स्थापित करूं?

try: 
    import foo 
except ImportError: 
    install_the_module("foo") 

सिफारिश/मुहावरेदार इस परिदृश्य को संभालने के लिए तरीका क्या है?

मैंने देखा है कि बहुत सी स्क्रिप्ट्स बस एक त्रुटि या चेतावनी मुद्रित करती हैं जो उपयोगकर्ता को लापता मॉड्यूल के बारे में सूचित करती है और (कभी-कभी) इंस्टॉल करने के तरीके पर निर्देश प्रदान करती है। हालांकि, अगर मुझे पता है कि मॉड्यूल PyPI पर उपलब्ध है, तो मैं निश्चित रूप से स्थापना प्रक्रिया शुरू करने के लिए एक कदम आगे ले सकता हूं। नहीं?

+4

इसका सिद्धांत में अच्छा लेकिन वास्तविकता में पिछवाड़े में अपने एक दर्द। बस उपयोगकर्ताओं को संकुल को स्थापित करने के लिए प्राप्त करें या निर्भरता के रूप में अपना पैकेज बनाते समय उन्हें प्रदान करें। –

+2

@ जैकोब बॉयर - आपका पहला वाक्य उन चीजों को बताता है जिन्हें लोगों को भुगतान करने के लिए भुगतान किया जाता है - अगर कुछ अच्छा विचार था और करना मुश्किल नहीं था तो यह किसी भी व्यक्ति को पीआईटीए के माध्यम से किसी और को भुगतान करने की आवश्यकता के बिना पहले से ही किया जाएगा। मुझे एक स्क्रिप्ट लिखने के लिए काम पर भुगतान किया गया था, जो अलग-अलग तैनाती को स्वचालित करता था और बिना किसी उपयोगकर्ता इंटरैक्शन के चलाया जा सकता था, इसलिए मुझे उस मामले को स्वचालित रूप से संभालने की आवश्यकता थी जहां पाइथन मॉड्यूल पहले से स्थापित नहीं थे। अब दुनिया को जो करने के लिए भुगतान किया गया था उससे फायदा हो सकता है - मैंने इसे नीचे दस्तावेज किया: http://stackoverflow.com/a/25643988/901641 – ArtOfWarfare

+0

5 अपवॉट्स आपकी पायथन शैली पीईपी 8 –

उत्तर

21

स्थापना समस्याएं स्रोत कोड का विषय नहीं हैं!

install_requires कॉन्फ़िगरेशन का उपयोग करके आप अपने पैकेज के setup.py के अंदर अपनी निर्भरताओं को सही ढंग से परिभाषित करते हैं।

यह तरीका है ... ImportError के परिणामस्वरूप कुछ स्थापित करना अजीब और डरावना है। ऐसा मत करो

+0

यह उस स्थिति में मदद नहीं करता है जहां आवश्यक मॉड्यूल को setup.py द्वारा आवश्यक है, हालांकि। क्या किसी प्रकार का एक हुक है जो सेटअप() प्रदान करता है जो इसे setup_requires के माध्यम से सेटअप-समय निर्भरता स्थापित करने की अनुमति दे सकता है और उसके बाद अत्यधिक बॉयलरप्लेट जोड़ने के बिना, उसी कॉल के भीतर उस नई कॉल निर्भरता में परिभाषित कमांड क्लास का उपयोग कर सकता है उस निर्भरता का उपयोग करने वाले प्रत्येक पैकेज के लिए setup.py के लिए? – hosford42

+0

मैंने जोड़ा [एक नया सवाल] (http://stackoverflow.com/questions/37551598/providing-a-custom-command-class-to-setup-py-in-a-separately-installed-package) मेरे पते को संबोधित करने के लिए विशिष्ट उपयोग केस। – hosford42

15
try: 
    import foo 
except ImportError: 
    sys.exit("""You need foo! 
       install it from http://pypi.python.org/pypi/foo 
       or run pip install foo.""") 

उपयोगकर्ता की स्थापना को स्पर्श न करें।

5

यहां एक समाधान है जिसे मैंने एक साथ रखा है जिसे मैं pyInstall.py पर कॉल करता हूं। यह वास्तव में जांचता है कि ImportError पर निर्भर होने के बजाय मॉड्यूल स्थापित है या नहीं, यह try/except के बजाय if के साथ इसे संभालने के लिए मेरी राय में क्लीनर दिखता है)।

मैंने इसे संस्करण 2.6 और 2.7 के तहत उपयोग किया है ... यदि यह print को फ़ंक्शन के रूप में संभाल नहीं लेता है तो शायद यह पुराने संस्करणों में काम करेगा ... और मुझे लगता है कि यह संस्करण 3.0+ में काम करेगा लेकिन मैंने कभी कोशिश नहीं की है।

इसके अलावा, जैसा कि मैं अपने getPip समारोह की टिप्पणियों में ध्यान दें, मुझे नहीं लगता कि विशेष रूप से समारोह ओएस एक्स

from __future__ import print_function 
from subprocess import call 

def installPip(log=print): 
    """ 
    Pip is the standard package manager for Python. Starting with Python 3.4 
    it's included in the default installation, but older versions may need to 
    download and install it. This code should pretty cleanly do just that. 
    """ 
    log("Installing pip, the standard Python Package Manager, first") 
    from os  import remove 
    from urllib import urlretrieve 
    urlretrieve("https://bootstrap.pypa.io/get-pip.py", "get-pip.py") 
    call(["python", "get-pip.py"]) 

    # Clean up now... 
    remove("get-pip.py") 

def getPip(log=print): 
    """ 
    Pip is the standard package manager for Python. 
    This returns the path to the pip executable, installing it if necessary. 
    """ 
    from os.path import isfile, join 
    from sys  import prefix 
    # Generate the path to where pip is or will be installed... this has been 
    # tested and works on Windows, but will likely need tweaking for other OS's. 
    # On OS X, I seem to have pip at /usr/local/bin/pip? 
    pipPath = join(prefix, 'Scripts', 'pip.exe') 

    # Check if pip is installed, and install it if it isn't. 
    if not isfile(pipPath): 
     installPip(log) 
     if not isfile(pipPath): 
      raise("Failed to find or install pip!") 
    return pipPath 

def installIfNeeded(moduleName, nameOnPip=None, notes="", log=print): 
    """ Installs a Python library using pip, if it isn't already installed. """ 
    from pkgutil import iter_modules 

    # Check if the module is installed 
    if moduleName not in [tuple_[1] for tuple_ in iter_modules()]: 
     log("Installing " + moduleName + notes + " Library for Python") 
     call([getPip(log), "install", nameOnPip if nameOnPip else moduleName]) 

यहाँ कुछ उदाहरण हैं उपयोग के तहत काम करेगा:

from datetime import datetime 
from pyInstall import installIfNeeded 

# I like to have my messages timestamped so I can get an idea of how long they take. 
def log(message): 
    print(datetime.now().strftime("%a %b %d %H:%M:%S") + " - " + str(message)) 

# The name fabric doesn't really convey to the end user why the module is needed, 
# so I include a very quick note that it's used for SSH. 
installIfNeeded("fabric", notes = " (ssh)", log = log) 

# SoftLayer is actually named softlayer on pip. 
installIfNeeded("SoftLayer", "softlayer", log = log) 

संपादित: pipPath होने का एक और अधिक पार मंच तरीका है:

from subprocess import Popen, PIPE 
finder = Popen(['where' if isWindows() else 'which', 'pip'], stdout = PIPE, stderr = PIPE) 
pipPath = finder.communicate()[0].strip() 

यह धारणा बनाता है कि pip सिस्टम पथ पर स्थापित/स्थापित किया जाएगा। यह गैर-विंडोज प्लेटफ़ॉर्म पर बहुत विश्वसनीय है, लेकिन विंडोज़ पर मेरे मूल उत्तर में कोड का उपयोग करना बेहतर हो सकता है।

5

नकारात्मक वोटों को जोखिम देने, मैं एक त्वरित हैक का सुझाव देना चाहता हूं। कृपया ध्यान दें कि मैं स्वीकार्य उत्तर के साथ पूरी तरह से बोर्ड पर हूं कि निर्भरताओं को बाहरी रूप से प्रबंधित किया जाना चाहिए।

लेकिन स्थितियों में, जहां आप पूरी तरह कुछ है कि निहित आत्म की तरह काम करता हैक करने की जरूरत के लिए, आप कुछ नीचे की तरह की कोशिश कर सकते हैं:

import os 

try: 
    import requests 
except ImportError: 
    print "Trying to Install required module: requests\n" 
    os.system('python -m pip install requests') 
# -- above lines try to install requests module if not present 
# -- if all went well, import required module again (for global access) 
import requests 
+1

os.system को बहिष्कृत किया गया है ... उपप्रोसेसर मॉड्यूल का उपयोग करें –

संबंधित मुद्दे