百科问答小站 logo
百科问答小站 font logo



python setup.py data_files 设置要拷贝的文件,不能拷贝到安装目录下。要怎样解决? 第1页

  

user avatar   liu-ji-27-94 网友的相关建议: 
      

最近恰巧也遇到了这个问题,网上貌似没有完整详细的解答。解释一下我对题主的意思的理解:在使用python的setup.py将项目打包成wheel时,需要打包项目外的静态文件,但是无论setup的data_files参数如何设置,打包得到的轮子在安装后,静态文件都无法自动存储于该库的安装目录下。这其实是由于setup打包轮子的脚本不鼓励绝对路径,而相对路径是基于sys.prefix的。所以想要自动存储在安装目录下,可以死了这条心了。

王炳明:花了两天,终于把 Python 的 setup.py 给整明白了 这篇文章是我在全网看到的对setuptool讲解最为细致全面的,但是当然它没有提到题主的问题。下面我详细解释一下data_files参数,也作为一个学习的记录。

静态文件是什么

这里指的是除去*.py文件以外的其他类型的文件。我尝试过将包含图片和网页文件的文件夹作为package进行打包,企图通过这种方式把静态文件包含在轮子里。事实证明轮子安装后这个文件夹下只有_init_.py一个文件。在打包时,我们一般把静态文件综合起来放在top-level的package外面,即和setup.py同级目录下。

两种静态文件打包方法

在打包egg、tar.gz等格式时,编写MANIFEST.in将静态文件的路径include进来,注意这里的语法支持通配符,参考Python打包时包含静态文件处理方法。相关文章很多,大多互相抄袭而且不给引用,强烈谴责,因为我也找不到最早的原创了,在此引一篇还算清晰的。

在打包whl格式时,不需编写MANIFEST.in,而是通过data_files参数将静态文件路径包含进来,并指定安装时的存储位置。在3.1版本之后的setup中,不设置模板文件MANIFEST.in时,会将data_files中的文件自动添加到MANIFEST中。提一下另外一位答主的答案,的确可以不使用sdist参数来打包,但是对于必须使用whl格式的场景,这个问题是绕不开的,毕竟轮子现在是python的官方标准二进制文件,并且在pypi上发布时也需要。

data_files参数详解

参考官方文档2. Writing the Setup Script,以下是我的翻译和注解。

data_files参数可以用于指定模块发布所需的额外文件:配置文件、信息目录、数据文件和其他前文没有提到的文件类型。文档中前文提到了包数据文件*.dat,编写python语言扩展模块时可能用到的*.c和*.i。

data_files按照下面例子中给出的方式指定了一个(directory, files)对儿的列表。

       setup(..., data_files=[     ('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),      ('config',  ['cfg/data.cfg']) ],)     

每一个(directory, files)对儿指定了安装时文件的存储路径,和文件目前存储的位置。

后者files是相对于setup.py脚本的相对路径。注意你可以指定安装时存储的路径,却不能在安装时自动给文件重命名。files中文件夹的名字不会影响安装时路径的命名,这里只关心文件的名字。

前者directory的安装存储路径同样应为相对路径,它相对于安装前缀(系统级安装时为sys.prefix,用户级安装时为site.USER_BASE,我们一般都是系统级安装。)Distutil在最上面引用的那篇文章中有提到,是setup的前身,支持绝对路径,但是在打包轮子的脚本里面故意去掉了这个支持。这种改进的用心其实很好理解,你可以输出这几个路径观察一下,我的电脑上是这样的:

       >>> import sys >>> sys.prefix '/Users/liushangyu/opt/anaconda3' >>> sys.exec_prefix '/Users/liushangyu/opt/anaconda3' >>> get_python_lib() '/Users/liushangyu/opt/anaconda3/lib/python3.8/site-packages'     

题主肯定是和我最初一样希望静态文件能随着库文件夹都安装在get_python_lib()的路径下,但是不同用户的python版本不同,安装路径也可能不同,就无法确定这个前缀lib/python3.8/site-packages中的python3.8具体是多少了。为了安装时的兼容性,我们当然不能设置绝对路径。

我试验设置绝对路径,setup将我的绝对路径拼接在get_python_lib()路径后面得到一个超级深的目录;我试验设置相对路径前面加上/,因为怀疑绝对路径是由于有/而导致的,结果路径无法解析;我试验拼接上get_python_lib()减去sys.prefix的那部分,结果又拼接到了get_python_lib()上面;只有在直接设置一个和get_python_lib()中的路径不重合的相对路径时,是拼接到sys.prefix上面的。

这个问题在Github的issue中也有讨论:bdist_wheel makes absolute data_files relative to site-packages。我不知道目前与更高版本的python兼容的setuptool是否有更高版本,我的一个朋友发布时用的是Python3.9环境下的绝对路径,我不知道他怎么成功的。




  

相关话题

  Python 怎么二次封装一个系统函数? 
  如何用python读取下面的csv文件? 
  按键精灵等以GUI接口为基础的程序在爬虫界的地位是怎样的? 
  掌握很多门计算机语言的人不会记串吗? 
  Python 打包成 exe,太大了该怎么解决? 
  学习python与c语言哪个好? 
  如何评价 Python 基础知识难度大吗? 
  很多网站源码都是分为 GBK 和 UTF-8 版,为什么要同时开发两种? 
  一个程序员多年累计编写一百万行代码是什么体验? 
  python中的模块、库、包有什么区别? 

前一个讨论
Python如何调用一个py文件并输出部分行内容?
下一个讨论
1 月 6 日河北新增本土确诊病例 51 例,69 例无症状感染者,目前当地防控情况如何?





© 2024-06-09 - tinynew.org. All Rights Reserved.
© 2024-06-09 - tinynew.org. 保留所有权利