python自己造轮子使用

项目结构

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

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

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__)

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

import rofunc as rf
rf.xsens.data_clean(...)

1.需要在一级__init__.py中

from __future__ import absolute_import

from .devices import xsens, optitrack, ...
  1. 二级__init__.py空着
  2. 三级__init__.py
from __future__ import absolute_import

from .record import *
from .process import *

具体在你的包中该如何组织多层__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文件中。

实例

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",
    ],
)

这里重点介绍一下 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/:

详情请参见 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

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      # 也可以一起写,省事

或者直接

python -m build

本地安装


执行完之后会在当前目录生成 dist 文件夹,文件夹内部是编译好的 python 包,whl 后缀结尾

cd dist
执行安装命令

pip install rofunc-0.0.0.9-py3-none-any.whl
卸载

pip uninstall rofunc
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值