2016-05-29 76 views
1

我想创建一些简单易用的pip包,用于在Python中加载常见的机器学习数据集。 (是的,有些东西已经存在,但我希望它是更简单。)使用setuptools时,如何在安装时下载外部数据?

我想实现的是:

  • 用户运行pip install dataset
  • PIP下载数据集,说通过wget http://mydata.com/data.tar.gz。请注意,数据不在python包本身中,而是从其他地方下载。
  • pip从该文件中提取数据并将其放入安装该软件包的目录中(这并不理想,但数据集非常小,因此我们假设在这里存储数据并不是什么大问题。)
  • 稍后,当用户导入我的模块时,模块会自动从特定位置加载数据。

这个问题是关于子弹2和3.有没有办法用setuptools做到这一点?

回答

1

正如Kevin暗示的那样,Python软件包的安装应该是完全可重复的,并且任何潜在的外部下载问题都应该推送到运行时。因此不应该用setuptools来处理。

相反,为避免给用户造成负担,请考虑在加载时以懒惰的方式下载数据。例如:

def download_data(url='http://...'): 
    # Download; extract data to disk. 
    # Raise an exception if the link is bad, or we can't connect, etc. 

def load_data(): 
    if not os.path.exists(DATA_DIR): 
     download_data() 
    data = read_data_from_disk(DATA_DIR) 
    return data 

然后我们可以描述在文档download_data,但大多数用户会永远不需要管它。这与imageio模块在运行时下载必要的解码器的行为有些类似,而不是让用户自己管理外部下载。

0

Python软件包安装指出,为了安装Python软件包,它永远不应该执行Python代码。这意味着您可能无法在安装过程中下载内容。

如果您想要下载一些附加数据,请在安装软件包后执行此操作,例如,当您导入软件包时,可以下载此数据并将其缓存到某处,以便在每次新导入时都不要下载它。

+0

进口副作用是邪恶的。最好提供一个明确地做到这一点的函数。例如,如果用户没有互联网,或者在某种邪恶的MitM代理的后面,给你一个“这个页面被阻止”的HTML文件而不是你期望的数据集? – Kevin

0

请注意,数据并不驻留在python包本身,而是从其他地方下载。

请不要这样做。

Python包装的重点在于提供一个完全确定的,可重复的,可重复使用的方法,每次安装完全一样的东西。您的建议已至少存在以下问题:

  • 最终用户可能下载你的包在计算机A上,把它粘拇指驱动器上,然后在不具备上网计算机B上安装它。
  • Web上的数据可能会更改,这意味着安装相同确切软件包的两个人会得到不同的结果。
  • 提供该数据的网站可能会不存在或unwisely change the URL,这意味着仍有该软件包的用户将无法使用该软件。
  • 用户可能位于互联网过滤器的后面,您可能会得到一个无用的“此页面被阻止”的HTML文件,而不是您期望的数据集。

相反,您应该包括与包(使用package_data or data_files参数setup())数据,或者在你的Python代码手动下载数据,当用户准备确实提供了一个单独的顶级功能所以。

+0

假设由于许可问题而无法分发数据。然后我认为你所说的是,在运行时出现的问题比安装时更好。是? (有没有想过这个..我想我同意。)也许我会做的是在运行时有一个懒惰的自动下载,可以有点失败。 – rd11

+0

否。显式优于隐式。用户不希望导入包来做任何事情。提供手动启动下载的功能。 – Kevin

+0

我并不是说它会在导入时发生,手动下载在绝大多数情况下不过是不必要的麻烦。 – rd11

相关问题