通过pypi包来降低代码的复杂性和避免重复代码

除了计算机本身,子程序是计算机科学中最伟大的发明。(引自《代码大全》)

通过包来实现代码复用

问题的提出

  问题的提出可以总结为如下的两种情形:情形1来源于之前看到的一个问答网站上的用户提问:程序员需要记忆代码吗?情形2来源于实际工作场景的归纳总结:在代码工程A中,存在一个utils模块,该模块里面存放供该工程中其他代码文件所调用的一些通用子函数。该项目完结,进入一个新的项目,相关的代码工程称之为代码工程B,在开发的过程中,会遇到B中的utils模块需要与A中类似甚至一致的通用函数方法。此时可以手动将老项目中的utils模块中的相关函数代码复制一份过来,修修改改用起来。但这样做除了额外的工作量之外(哈哈是的,复制粘贴也需要工作量的),还会带来一个经典的软件问题:“平行维护”。相同(似)的代码被放置多处,每一处的修正、改进无法同步至其他处。
  本文是尝试对上述问题的解答:以python语言为例,可以将这些在多个项目中通用的方法收集起来,然后构建、管理自己的pypi包。

制作自己的pypi包

注册pypi账号

  pypi官网的账号为https://pypi.org/,可能需要vpn才能访问。注册完之后,应该具有以下三个要素:

  • 账号名
  • 密码
  • token

构建pypi包

  举一个最简单的例子,该pypi的包的名字为toytool,如果想安装该包的做法是:pip install toytool。它的作用是提供通用库函数ReadImage,该函数支持opencv和pillow两种图像处理库的方式打开图片。

import ttool
from ttool.read import ReadImage
imgOpencv = ReadImage("1.png", "opencv")  # 以opencv的方式打开图片
imgPillow = ReadImage("1.png", "pillow")  # 以pillow的方式打开图片

  toytool包的代码树如下图所示:

  setup.py文件中的内容为:

import setuptools

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()  # 显示在pypi官网页面上的项目介绍

setuptools.setup(
    name="toytool",  # 决定了pip install toytool的时候包的名称
    version="0.0.1",
    author="HandsomeBoy",
    author_email="xxx@163.com",
    description="toy-tool",  # 显示在pypi官网页面上的项目介绍(简介)
    long_description=long_description,
    long_description_content_type="text/markdown",
    packages=setuptools.find_packages(),
    python_requires=">=3.6",
    install_requires=["pillow", "opencv-python", "opencv-python-headless"]  # ReadImage的依赖项,在安装pip install toytool的时候,会安装该依赖项
)

  ttool文件夹名称决定了在包调用的时候,import的名称,例如这里为:

import ttool
from ttool.read import ReadImage

  read.py中的内容如下所示:

import cv2
import typing
from PIL import Image

def ReadImage(ImagePath: str, Mode: str = 'cv2') -> typing.Any:
    """Read image in one manner of opencv or pillow.

    Args:
        ImagePath: img file path.
        Mode: one of ['pillow', 'cv2'].
    """
    if mode == 'pillow':
        img = Image.open(ImagePath)
    elif mode == "opencv":
        img = cv2.imread(ImagePath)
    return img

上传pypi包

  上传之前先安装pip install twine。然后正式上传:

cd toytool
python3 setup.py sdist
twine upload dist/*

rethink

  该方案在实际的工作中使用起来还是很不错的,当然本文举的这个是最简单的读图片的例子,实际上自己的通用函数包更加丰富:写图片,读json,写json,在图片上绘制文字,绘制形状等等都可以不断的纳入、丰富自己的pypi包里面。
  有了pypi包,一定程度上降低了代码的复杂性:“在编写包时,需要考虑细枝末节。但一旦包写好之后,程序员就可以忘记这些细节,在不了解其内部工作原理的情况下使用该包”。具体到本文的例子,opencv和pillow打开图片的方式,一个为read一个为open,这些繁杂的信息在包封装之后归为统一ReadImage。关于如何看待程序员需要记忆代码的问题?问答网站上,大家回答的大概意图基本上是:“我不需要知道一切。我只需要知道在哪里可以找到它。”这回答有一定的道理,但本文可以作为该回答的一定补充。因为毕竟翻阅文档也需要耗费一定的时间,而且如果旁边有同事看着的时候,一些常规的操作,如果需要查阅文档,也显得挺尴尬,但同时程序员的大脑是最宝贵的资源,通过包来主导、统一自己的模式是一个降低记忆的手段。
  有了pypi包,一定程度上避免了重复代码的问题,进而避免了“平行维护”的问题。
  再有就是C++也可以总结自己的通用函数库,对应pypi包的管理方式称之为conan。后续计划另开一篇介绍cona包管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值