在python脚本中包含python模块(依赖项)安装

时间:2014-09-28 05:28:32

标签: python python-module

在运行实际/主脚本之前,有没有办法首先包含/调用python模块(依赖项)安装?

例如,在我的main.py中:

import os, sys
import MultipartPostHandler

def main():
    # do stuff here

但是还没有安装MultipartPostHandler,所以我想要的是先安装它 实际上运行main.py ...但是以自动方式运行。当我自动说,我的意思是我将只调用一次脚本来启动依赖安装,然后是主脚本的实际功能。 (不知何故,与maven有点类似。但我只需要安装部分)

我已经了解setuptools的基础知识。问题是我可能需要分别调用安装(setup.py)和主脚本(main.py)。

非常感谢任何想法。提前谢谢!

3 个答案:

答案 0 :(得分:4)

  

在运行实际/主脚本之前,有没有办法首先包含/调用python模块(依赖项)安装?

  • 一种好方法是使用setuptools并在install_requires明确列出它们。
  • 由于您提供main功能,因此您可能还想提供entry_points
  

我已经了解setuptools的基础知识。问题是我可能需要分别调用安装(setup.py)和主脚本(main.py)。

这通常不是问题。首先使用requirements.txt文件和pip install -r requirements.txt安装所有内容是很常见的。此外,如果列出依赖关系,那么您可以合理地期望在调用函数时它将存在并且不依赖于try/except ImporError。期望存在所需的依赖关系是一种合理的方法,并且只使用try/except作为可选的依赖项。

setuptools 101:

创建一个这样的树结构:

$ tree
.
├── mymodule
│   ├── __init__.py
│   └── script.py
└── setup.py

您的代码将在mymodule下;让我们想象一些执行简单任务的代码:

# module/script.py    

def main():
    try:
        import requests
        print 'requests is present. kudos!'
    except ImportError:
        raise RuntimeError('how the heck did you install this?')

这是一个相关的设置:

# setup.py

from setuptools import setup
setup(
    name='mymodule',
    packages=['mymodule'],
    entry_points={
        'console_scripts' : [
            'mycommand = mymodule.script:main',
        ]
    },
    install_requires=[
        'requests',
    ]
)

这会使您的main可用作命令,这也可以安装您需要的依赖项(例如requests

~tmp damien$ virtualenv test && source test/bin/activate && pip install mymodule/
New python executable in test/bin/python
Installing setuptools, pip...done.
Unpacking ./mymodule
  Running setup.py (path:/var/folders/cs/nw44s66532x_rdln_cjbkmpm000lk_/T/pip-9uKQFC-build/setup.py) egg_info for package from file:///tmp/mymodule

Downloading/unpacking requests (from mymodule==0.0.0)
  Using download cache from /Users/damien/.pip_download_cache/https%3A%2F%2Fpypi.python.org%2Fpackages%2F2.7%2Fr%2Frequests%2Frequests-2.4.1-py2.py3-none-any.whl
Installing collected packages: requests, mymodule
  Running setup.py install for mymodule

    Installing mycommand script to /tmp/test/bin
Successfully installed requests mymodule
Cleaning up...
(test)~tmp damien$ mycommand 
requests is present. kudos!

更有用的命令与argparse:

如果您想使用argparse,那么......

# module/script.py

import argparse

def foobar(args):
    # ...

def main():
    parser = argparse.ArgumentParser()
    # parser.add_argument(...)
    args = parser.parse_args()
    foobar(args)

答案 1 :(得分:0)

您应该使用imp模块。这是一个例子:

import imp
import httplib2
import sys

try:
  import MultipartPostHandler
except ImportError:
  # Here you download 
  http = httplib2.Http()
  response, content = http.request('http://where_your_file_is.com/here')
  if response.status == 200:
    # Don't forget the right managment
    with open('MultipartPostHandler.py', 'w') as f:
     f.write(content)
    file, pathname, description = imp.find_module('MultipartPostHandler')
    MultipartPostHandler = imp.load_module('MultipartPostHandler', file, pathname, description)
  else:
    sys.exit('Unable to download the file')

要获得完整的方法,请使用队列:

download_list = []
try:
    import FirstModule
except ImportError:
    download_list.append('FirstModule')

try:
    import SecondModule
except ImportError:
    download_list.append('SecondModule')

if download_list:
    # Here do the routine to dowload, install and load_modules

# THe main routine
def main():
    the_response_is(42)

您可以使用open(file_content, 'wb')

下载二进制文件

我希望它有所帮助

BR

答案 2 :(得分:0)

有几种方法可以做到这一点。一种方法是使用import ... try块包围except ImportError语句,然后使用一些Python代码来安装包,如果引发了ImportError异常,那么类似于:< / p>

try:
    import MultipartPostHandler
except ImportError:
    # code that installs MultipartPostHandler and then imports it

我不认为这种方法很干净。此外,如果存在其他无关的导入问题,则此处无法检测到。更好的方法可能是使用bash脚本检查模块是否已安装:

pip freeze | grep MultipartPostHandler

如果没有,请安装模块:

pip install MultipartPostHandler

然后我们可以安全地运行原始的Python代码。

编辑:实际上,我更喜欢FLORET的答案。 imp模块正是您想要的。