代码之家  ›  专栏  ›  技术社区  ›  norok2

使用setup.py++pip跨平台支持“数据文件”`

  •  1
  • norok2  · 技术社区  · 6 年前

    什么是跨平台运输 data_files 具有 setup.py (与 pip )?

    从官方文件来看,需要写:

    setup(...,
        data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                    ('config', ['cfg/data.cfg']),
                    ('/etc/init.d', ['init-script'])]
        )
    

    'bitmaps' ,等是这些文件应该放在的子目录(相对于 sys.prefix )中。

    但是,对于标准子目录将依赖于系统的跨平台安装,这是次优的。 此外,在开发人员模式下安装包不会将文件放在安装后的位置,这使得查找/使用资源的过程最终难以调试/烦人。

    我已经调查过了 appdirs ,但似乎很难在安装过程中使其正常工作,例如,如果使用用户目录来存储数据,这实际上会与我的开发环境相关联。

    我问这个问题的原因是因为我有一个小的Python包,它实现了一个简单的GUI,我想附带一个图标。

    记录在案,我可以处理 Stuff.Py 具有 setuptools 是的。

    2 回复  |  直到 6 年前
        1
  •  2
  •   hoefling    5 年前

    如注释中所建议的,为了捆绑资源文件,我宁愿使用package_data并将文件放在某个package dir下例子:

    project
    ├── pkg1
    │   ├── __init__.py
    │   └── icons
    │       └── image.png
    └── pkg2
        └── __init__.py
    

    包装在 setup.py 脚本:

    from setuptools import setup
    
    
    setup(
        ...
        package_data={'pkg1': ['icons/image.png']},
    )
    

    更新以访问代码中的资源文件:

    引入Python3.7 importlib.resources 它取代了旧的 pkg_resources 功能性,并提供一个利用 pathlib :

    filepath = importlib_resources.path('pkg1', 'icons/image.png')
    

    对于Python3.6及更高版本,有一个名为 importlib_resources . 因此,版本不可知的例子是:

    import sys
    
    if sys.version >= (3, 7):
        from importlib import resources as importlib_resources
    else:
        import importlib_resources
    
    filepath = importlib_resources.path('pkg1', 'icons/image.png')
    

    使用 重要资源 而不是 包装资源 如果可能的话。

    原来的答案,只为历史

    要在代码中引用资源文件,请使用 包装资源 :

    import pkg_resources
    
    filepath = pkg_resources.resource_filename('pkg1', 'icons/image.png')
    

    因此,跨平台支撑由 包装资源 . 参考 ResourceManager API 以获取可用的资源访问功能。

        2
  •  0
  •   Tobey    6 年前

    更新 查看 solution 从@ hoefling

    这个 data_files 选项指定要为包上载的文件。

    docs :

    不使用文件中的目录信息来确定已安装文件的最终位置;只使用文件名。

    如果要构建跨平台目录路径,请使用 os 模块

    import os
    
    path = os.path.join('root', 'directory')
    

    如果您想确定平台何时有人试图构建您的包,请使用 sys 模块

    import sys
    
    current_platform = sys.platform.lower()
    is_windows = current_platform.startswith('win')
    is_ubuntu =  'ubuntu' in current_platform
    is_mac = 'darwin' in current_platform
    
    
    if is_windows:
         ... # windows specific dayta
    
    elif is_ubuntu:
         ....
    
    else:
        raise Exception('Platform not supported')