2013-06-21 3 views
4

Я хочу написать сценарий для автоматической установки новой установки ubuntu и установки приложения на основе django. Поскольку скрипт будет запущен на новом сервере, скрипт Python должен автоматически установить некоторые требуемые модули.Как установить и импортировать модули Python во время выполнения?

Вот сценарий.

#!/usr/bin/env python 

import subprocess 
import os 
import sys 

def pip_install(mod): 
    print subprocess.check_output("pip install %s" % mod, shell=True) 

if __name__ == "__main__": 
    if os.getuid() != 0: 
     print "Sorry, you need to run the script as root." 
     sys.exit() 

    try: 
     import pexpect 
    except: 
     pip_install('pexpect') 
     import pexpect   

    # More code here... 

Установка pexpect успех, однако следующая строка import pexpect неудачен. Я думаю, потому что во время выполнения код не знает о недавно установленном pexpect.

Как установить и импортировать модули Python во время выполнения? Я открыт для других подходов.

+1

непроверенных: 'pexpect = __import __ ('pexpect')' –

ответ

2

Я решил свою проблему с помощью imp модуля.

#!/usr/bin/env python 

import pip 
import imp 

def install_and_load(package): 
    pip.main(['install', package]) 

    path = '/usr/local/lib/python2.7/dist-packages' 
    if path not in sys.path: 
     sys.path.append(path) 

    f, fname, desc = imp.find_module(package) 
    return imp.load(package, f, fname, desc) 

if __name__ == "__main__": 
    try: 
     import pexpect 
    except: 
     pexpect = install_and_load('pexpect') 

    # More code... 

На самом деле код не идеален, так как мне нужно жестко установить каталог модулей Python. Но поскольку сценарий предназначен для известной целевой системы, я думаю, что все в порядке.

5

Вы можете импортировать пипс вместо использования подпроцесс:

import pip 

def install(package): 
    pip.main(['install', package]) 

# Example 
if __name__ == '__main__': 
    try: 
     import pexpect 
    except ImportError: 
     install('pexpect') 
     import pexpect 

другой дубль:

import pip 

def import_with_auto_install(package): 
    try: 
     return __import__(package) 
    except ImportError: 
     pip.main(['install', package]) 
    return __import__(package) 

# Example 
if __name__ == '__main__': 
    pexpect = import_with_auto_install('pexpect') 
    print(pexpect) 

[править]

Вы должны рассмотреть возможность использования requirements.txt вместе с пип. Похоже, вы пытаетесь автоматизировать развертывание (и это хорошо!), В моем поясе инструмента у меня также есть virtualenvwrapper, vagrant и ansible.

Это выход для меня:

(test)[email protected]:~/test# pip uninstall pexpect 
Uninstalling pexpect: 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/ANSI.py 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/ANSI.pyc 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/FSM.py 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/FSM.pyc 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/fdpexpect.py 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/fdpexpect.pyc 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/pexpect-2.4-py2.6.egg-info 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/pexpect.py 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/pexpect.pyc 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/pxssh.py 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/pxssh.pyc 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/screen.py 
    /usr/lib/python-environments/test/lib/python2.6/site-packages/screen.pyc 
Proceed (y/n)? y 
    Successfully uninstalled pexpect 
(test)[email protected]:~/test# python test.py 
Downloading/unpacking pexpect 
    Downloading pexpect-2.4.tar.gz (113Kb): 113Kb downloaded 
    Running setup.py egg_info for package pexpect 
Installing collected packages: pexpect 
    Running setup.py install for pexpect 
Successfully installed pexpect 
Cleaning up... 
<module 'pexpect' from '/usr/lib/python-environments/test/lib/python2.6/site-packages/pexpect.pyc'> 
(test)[email protected]:~/test# 
+0

Проблема по-прежнему сохраняется: установка выполняется успешно, но в результате импорта создается модуль ImportError: no module с именем pexpect. – flowfree

+0

Вы используете virtualenv? –

+0

Нет, я пишу и запускаю скрипт на новой установке ubuntu. Он только установил пакет 'python-pip'. – flowfree