• python自己造轮子使用


    项目结构

    首先,需要按照下列格式组织你的 package

    project                                    (项目名称,随意,与package无关)
        |----package                           (这个才是包名)
            |----__init__.py                   (__init__包内每个文件夹下都要有)
            |----code.py                       (具体的代码)
        |----other                             (package外可以放一些doc, img之类的,不会被封装到package中)
        |----__init__.py                       (空着即可)
        |----setup.py                          (构建脚本)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    init.py 如何写?
    对于包内的 init.py文件的写法,以下面的包内文件结构为例

    |----rofunc                                 (包名)
        |----devices                            (一级文件夹)
            |----xsens                          (二级文件夹)
                |----record.py                  (包含record函数)
                |----process.py                 (包含data_clean函数)
                |----__init__.py                (三级__init__)
            |----optitrack
                |----record.py
                |----process.py
                |----__init__.py
            |----...
            |----__init__.py                    (二级__init__)
        |----lfd
        |----...                    
        |----__init__.py                        (一级__init__)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    那么如果想要实现以下索引,该怎么写这几层的__init__.py呢?

    import rofunc as rf
    rf.xsens.data_clean(...)
    
    • 1
    • 2

    1.需要在一级__init__.py中

    from __future__ import absolute_import
    
    from .devices import xsens, optitrack, ...
    
    • 1
    • 2
    • 3
    1. 二级__init__.py空着
    2. 三级__init__.py
    from __future__ import absolute_import
    
    from .record import *
    from .process import *
    
    • 1
    • 2
    • 3
    • 4

    具体在你的包中该如何组织多层__init__.py,实际上要看你对于功能调用格式的设计了。

    setup.py 如何写?

    # -*- coding:utf-8 -*-
    from distutils.core import setup
    from setuptools import find_packages
    
    setup(name='declare',
            version='0.1',
            packages=find_packages(where='src\\'),  # 查找包的路径
            package_dir={'': 'src'},  # 包的root路径映射到的实际路径
            include_package_data=False,
            package_data={'data': []},
            description='A python lib for xxxxx',
            long_description='',
            author='python developer',
            author_email='xxxxxxx@qq.com',
            url='http://www.xxxxx.com/',  # homepage
            license='MIT',
            install_requires=['requests', 'selenium', 'baidu-aip', 'pillow', 'pywin32'],
            )
    # name : 打包后包的文件名
    # version : 版本号
    # author : 作者
    # author_email : 作者的邮箱
    # py_modules : 要打包的.py文件
    # packages: 打包的python文件夹
    # include_package_data : 项目里会有一些非py文件,比如html和js等,这时候就要靠include_package_data 和 package_data 来指定了。package_data:一般写成{‘your_package_name’: [“files”]}, include_package_data还没完,还需要修改MANIFEST.in文件.MANIFEST.in文件的语法为: include xxx/xxx/xxx/.ini/(所有以.ini结尾的文件,也可以直接指定文件名)
    # license : 支持的开源协议
    # description : 对项目简短的一个形容
    # ext_modules : 是一个包含Extension实例的列表,Extension的定义也有一些参数。
    # ext_package : 定义extension的相对路径
    # requires : 定义依赖哪些模块
    # provides : 定义可以为哪些模块提供依赖
    # data_files :指定其他的一些文件(如配置文件),规定了哪些文件被安装到哪些目录中。如果目录名是相对路径,则是相对于sys.prefix或sys.exec_prefix的路径。如果没有提供模板,会被添加到MANIFEST文件中。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    实例

    from setuptools import setup, find_packages
    
    setup(
        name="rofunc",
        version="0.0.0.9",
        description='The Full Process Python Package for Robot Learning from Demonstration',
        author="Junjia Liu",
        author_email="jjliu@mae.cuhk.edu.hk",
        url='https://github.com/Skylark0924/Rofunc',
        packages=find_packages(),
        install_requires=['matplotlib', 'pandas', 'tqdm', 'pillow', 'pytransform3d', 'tensorflow', 'numpy==1.21.6',
                          'nestle',
                          'pbdlib @ https://github.com/Skylark0924/Rofunc/releases/download/v0.0.0.7.1/pbdlib-0.1-py3-none-any.whl'],
        python_requires=">=3.6,<3.11",
        keywords=['robotics', 'learning from demonstration'],
        license='MIT',
        classifiers=[
            "Programming Language :: Python :: 3",
            "License :: OSI Approved :: MIT License",
            "Operating System :: OS Independent",
        ],
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    这里重点介绍一下 install_requires 的一些冷知识:如果依赖的包没有发布在PYPI,又不想/不能封在自己的包内,那么可以参照我对于 Sylvain Calinon 老师的pbdlib包的处理方法。

    pbdlib包是一个托管在 Gitlab 上的示教/模仿学习python库,原地址为 https://gitlab.idiap.ch/rli/pbdlib-python 。可以发现,这个库里是有setup.py的,但是只被用来做 git clone 之后的本地安装。我的解决方案是:

    本地打包(参照下一节的内容):git clone …
    python setup.py bdist_wheel sdist
    你会发现,主目录下会生成build和dist两个文件夹,dist下可以找被我们称作“轮子”的,对该库封装的压缩包pbdlib-0.1-py3-none-any.whl
    将其作为Release文件,上传到github的某个版本的Release中(当然,你自己有个人网站也是可以的,能够完整下载就行)
    在install_requires中,以包名+url的形式加入依赖’pbdlib @ https://github.com/Skylark0924/Rofunc/releases/download/v0.0.0.7.1/pbdlib-0.1-py3-none-any.whl’
    即可实现用户只需pip install rofunc,自动安装pbdlib依赖库。
    很遗憾的是,尽管这样的写法允许我们在本地安装的时候直接安装这些未上传到PYPI的依赖,但是由于规则限制,拥有这种直接链接的package无法被推送到pypi。会收到如下报错:

    HTTPError: 400 Client Error: '[your requirements]' is an invalid value for Version. Error: Can't use PEP 440 local versions. See https://packaging.python.org/specifications/core-metadata for url: https://test.pypi.org/legacy/:
    
    
    • 1
    • 2

    详情请参见 issue 430,以及这个链接。
    ·https://link.zhihu.com/?target=https%3A//github.com/pypa/twine/issues/430
    ·https://link.zhihu.com/?target=https%3A//resultfor.dev/670121-how-can-i-use-git-repos-as-dependencies-for-my-pypi-package

    包内数据
    Setuptools有关于这部分的教程,但是你会发现需要指定文件类型,而且每个文件夹下都要有一个__init__.py。这么麻烦的方式肯定不适合把整个文件夹的数据打包起来。于是,我就发现可以通过在project目录下再写一个 MANIFEST.in文件来实现。通过直接指定想要添加的数据路径就ok了
    
    recursive-include rofunc/data/ *
    recursive-include rofunc/simulator/assets/ *
    此外,还需要在setup.py文件中加一行来指向MANIFEST.in文件
    
    include_package_data=True
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Python setup.py和MANIFEST.in文件
    https://link.zhihu.com/?target=https%3A//blog.csdn.net/fragmentalice/article/details/44833013

    The MANIFEST.in template
    https://link.zhihu.com/?target=https%3A//docs.python.org/2/distutils/sourcedist.html%23the-manifest-in-template

    打包、安装与推送

    打包
    python setup.py bdist_wheel            # 打包为whl文件
    python setup.py sdist                  # 打包为tar.gz文件
    
    python setup.py bdist_wheel sdist      # 也可以一起写,省事
    
    • 1
    • 2
    • 3
    • 4
    • 5

    或者直接

    python -m build
    
    • 1

    本地安装

    
    执行完之后会在当前目录生成 dist 文件夹,文件夹内部是编译好的 python 包,whl 后缀结尾
    
    cd dist
    执行安装命令
    
    pip install rofunc-0.0.0.9-py3-none-any.whl
    卸载
    
    pip uninstall rofunc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    NFT Insider #64:电商巨头eBay提交NFT相关商标申请,毕马威将在Web3和元宇宙中投入3000万美元
    计算机毕业设计php_thinkphp_vue的约课管理系统-课程预约
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java家教服务平台y467g
    区别:千赫kHz、兆赫MHz、吉赫GHz、太赫THz、拍赫PHz、艾赫EHz每两级之间的换算以及之间的关系
    代码随想录训练营day52, 最长递增子序列, 最长连续递增序列, 最长重复子数组
    提升企业人效,从精细化考勤管理开始
    android ndk一些编译链接错误及解决办法
    Java的XWPFTemplate工具类导出word.docx的使用
    7.24 - 每日一题 - 408
    网络营销利器:海外IP代理如何助力你的网络营销?如何选择?
  • 原文地址:https://blog.csdn.net/weixin_45720992/article/details/134404323