根据一些开发人员的说法,Python是2019年排名前五的编程语言之一[1]。基于其开源社区的实力以及在新兴领域(例如大数据分析和机器学习)的高采用率,当人们谈论到其在未来几年的潜在发展趋势时,应该不会有人对此感到惊讶。由于Python软件包数量的逐年增长,这也使得越来越多的人开始关注Python包的开发中来。

本文的主要目的就是描述一个清晰的程序包结构,使开发人员更容易测试,构建和发布它,并在遵守相关默认约定的同时,尽可能编写少的配置。

一个清晰的工程结构

在开发一个Python包时,建议的文件夹和文件(包括测试内容)如下所示:

project-root├──src/   └──package_name/      └──__init__.py├──tests/   └──package_name/├──.coveragerc├──.gitignore├──LICENSE├──README.md├──setup.cfg└──setup.py

除了.gitignoreLICENSEREADME.md这三个文件外,上面的每一个文件在下面我们都会进行详细的介绍。如果对于上述三个文件有任何疑问,请自行上网查阅。

让我们首先开始从setup.py说起。setup.py是一个Python包的描述文件,它由一个Python脚本组成,并且可以在其中声明多个属性,如下所示:

from setuptools import find_packages, setup

setup(    name='python-package-cheat-sheet',    version='1.0.0',    author='Your Name',    author_email='you@yourdomain.com',    description='Python package developer\'s cheat sheet',    platforms='Posix; MacOS X; Windows',    packages=find_packages(where='./src'),    package_dir={        '': 'src'    },    include_package_data=True,    install_requires=(        'stringcase',    ),    classifiers=[        'Development Status :: 1 - Alpha',        'Natural Language :: English',        'Programming Language :: Python',        'Programming Language :: Python :: 3.6',        'Programming Language :: Python :: 3.7',    ],)

在这个文件中声明的各类属性都将会被Python管理器(如pip)或者是IDE(如PyCharm)进行组织起来,这就意味着所有的Python包都必须包含这么一个文件。

从上面的代码可以看到,一些属性的含义非常简单:名称(name),版本(version),作者(author)等。但是其他属性则需要一些解释:

  • packages,package_dir:用于设置包源文件的保存位置,及其声明的命名空间。在上面的示例中,scr是Python包源代码的根目录,并且在本示例中src下面还有一个子目录(package_name)。同时,只有当package_name中存在一个__init__.py文件时,该模块才会被加载到相应的索引路径中。
  • install_requires:一个包含整个包正常工作时所需要的依赖关系元组。甚至你还可以认为它是requirements.txt的替代品,如果你更熟悉后者的话。

这些属性使我们可以仅捆绑用户在使用我们提供的软件包时所需的文件,从而可以分发较小的Python分发文件。而且,他们将仅会下载每个Python程序包运行时所需要的依赖项,从而避免不必要的网络和存储开销。

这里有一个实际的练习可以看到它的效果, GitHub上也提供了相应的本文和示例代码:

https://github.com/ricardolsmendes/python-package-cheat-sheet

当然,我们也可以通过pip来安装这一项目,然后查重其相关依赖关系:

pip install git+https://github.com/ricardolsmendes/python-package-cheat-sheetpip freeze

此时,你将会看到有两个Python包被安装:

python-package-cheat-sheet==1.0.0stringcase==1.2.0

其中第一个包就是上面我们声明在setup.py中的Python包,而第二个就是安装第一个包所要依赖的包。

下面,让我们在Python的交互界面中调用方法package_cheat_sheet.StringFormatter.format_to_snakecase

python>>> from package_cheat_sheet import StringFormatter>>> print(StringFormatter.format_to_snakecase('FooBar'))foo_bar>>> exit()

正如你所见,foo_bar将作为StringFormatter.format_to_snakecase('FooBar')的结果进行输出,这就意味着上面整个安装过程是成功的。以上内容就快速演示了一个Python包的简单开发流程,并且介绍了如何通过几行代码就能将自己开发的Python包分享给其他用户。

必不可少的测试环节

现代软件的开发过程依赖于自动化的测试过程,如果没有它们我们甚至无法考虑开始开发Python软件包。为了达到这一目的,通常情况下Pytest是一个不二的选择,下面就让我们来看看如何进行使用。

首先,我们需要先卸载上面所安装的包,然后将其对应的代码克隆到本地,以源代码的形式进行安装:

pip uninstall python-package-cheat-sheetgit clone https://github.com/ricardolsmendes/python-package-cheat-sheet.gitcd python-package-cheat-sheetpip install --editable .

基于安装文件触发测试套件的命令是python setup.py test,并且默认情况下它不会使用pytest。但是,这里有另外一个方法来进行代替:即在这个Python包的根目录中创建一个setup.cfg文件,然后再为test命令设置一个别名。并且还可以在同一个文件中pytest

[aliases]test = pytest[tool:pytest]addopts = --cov --cov-report html --cov-report term-missing
  • 从现在开始,我们就需要为pytest来添加对应的依赖项,否则别名创建将会失败。下面,我们将依赖关系的不同属性添加到setup.py中:

    setup_requires=(    'pytest-runner',),tests_require=(    'pytest-cov',)

    其中pytest-runner负责为安装任务提供pytest支持;pytest-cov则是用来帮助我们生成代码的测试覆盖统计信息(将会在下面进行展示)。

同时,Python软件包的根文件夹中必须再包含一个配置文件:

  • .coveragerc:用于控制coverage脚本的范围。当项目中有不需要进行监视的测试文件夹时,此功能非常有用。在上述所示的工程项目中,仅src文件夹必须覆盖:

    [run]source = src

现在,我们准备运行python setup.py test进行测试。默认情况下,pytest将会在tests文件夹中查找对应的测试文件。对于刚刚克隆的GitHub仓库,其测试对应的预期输出为:

plugins: cov-2.8.1collected 10 itemstests/package_cheat_sheet/string_formatter_test.py ..........                                                                                                                                              [100%]---------- coverage: platform darwin, python 3.7.4-final-0 ---------Name                                          Stmts   Miss  Cover   --------------------------------------------------------------------src/package_cheat_sheet/__init__.py               2      0   100%src/package_cheat_sheet/string_formatter.py      17      0   100%--------------------------------------------------------------------TOTAL                                            19      0   100%Coverage HTML written to dir htmlcov

在运行结束pytest后,请同时也检查一下生成的htmlcov/index.html文件。因为当你需要对整个测试覆盖有一个更深入的理解时,查看这个文件是非常有必要的。


总结

本文介绍了一个清晰的Python包结构,涵盖了常规设置和测试工具。它通过使用Python标准和一些默认的约定在项目源码和测试文件之间建立了一个明显的界限。这使得我们在实际的操作过程中能够尽可能的减少代码的编写工作。

- END -

编程代码、技术探索、前沿追踪,你想要的这里都有!
转载请联系本公众号获得授权

未能加载包studio package_Python包开发者的必备清单相关推荐

  1. 错误: asp.net ajax 客户端框架未能加载.,ASP.NET Ajax 客户端框架未能加载、Sys未定义...

    在Windows Server 2003 系统上部署asp.net项目出现以下问题: IIS为6.0 导致菜单控件的图片显示不出来: WebSite:程序中的图片显示正常. 但用到ASP.net 2. ...

  2. VS2010未能加载 'VSTS for Database Professionals'包的解决办法

    VS2010未能加载 'VSTS for Database Professionals'包的解决办法: 开始菜单->Microsoft Visual Studio 2010->Visual ...

  3. R包库安装及数据加载:一次安装多个R包、一次加载多个R包

    R包库安装及数据加载:一次安装多个R包.一次加载多个R包 目录 R包库安装及数据加载 R包安装 一次安装多个R包 加载需要的R包

  4. sceneManager.loadscene加载场景时不会主动去加载场景的依赖包,要手动加载或添加场景到build setting列表中...

    sceneManager.loadscene加载场景时不会主动去加载场景的依赖包,要手动加载或添加场景到build setting列表中 假设有一场景1001.unity,,manifest文件如下: ...

  5. java spring包_java 自定义加载器,加载spring包,动态加载实现,jar包隔离,tomcat加载webapp方式...

    java 自定义加载器,加载spring包,动态加载实现,jar包隔离,tomcat加载webapp方式 发布时间:2018-08-20 12:02, 浏览次数:774 , 标签: java spri ...

  6. osmdroid 地图 加载离线地图资源包 zip格式

    osmdroid 加载离线地图资源包.我这只用了zip的.其他格式没试. storage/emulated/0/osmdroid/hefeiosm.zip 主要逻辑是,拷贝  hefeiosm.zip ...

  7. 未能加载虚拟光盘到虚拟电脑linux,VirtualBox 安装增强功能报 [未能加载虚拟光盘]...

    VirtualBox 安装增强功能报 [未能加载虚拟光盘] 本地搭了虚拟机 CentOS 7, 想做主机和虚拟机的文件共享, 需要安装增强功能, 但安装时报下图错误: 度娘上也找了很多文章, 基本上讲 ...

  8. “在解决方案中的一个或多个项目由于以下原因未能加载 项目文件或网站已移动或重新命名,或者不在您的计算机上” 的解决办法...

    用Visual studio.NET 2003/2005/2008在打开从网上下载的解决方案或从其他地方考来的解决方案时,往往会碰到一个这样的错误,提示说: "在解决方案中的一个或多个项目由 ...

  9. 安装grunt-browser-sync时报错:“未能加载Visual C++ 组件 “VCBuild.exe”

    报错环境:windows7 X64 , VS2012 报错内容: MSBUILD : error MSB3428: 未能加载 Visual C++ 组件"VCBuild.exe". ...

最新文章

  1. fiddler及postman讲解
  2. lumen 分页_lumen 中实现分表
  3. c/c++整理--c++面向对象(3)
  4. xp sp3 安装不了ie8
  5. 锚杆拉拔试验弹性模量计算_【安全宣教】煤亮子小课堂(十三)——锚杆的锚固力和拉拔力...
  6. java基本运算方法总结(ing)
  7. 斯坦福大学深度学习公开课cs231n学习笔记(3)最优化方法:梯度下降
  8. JAVA主类包涵其他类,Java application中的主类需包含main方法,以下哪项是main方法的正确形参?( )...
  9. linux设置进程开机启动,Linux应用程序开机自动启动设置方法
  10. 番外篇-使用脚本批量安装软件
  11. Visio方向键无法移动对象的解决办法[笔记本版]
  12. 梦幻109鸿蒙量星太难杀,梦幻西游:维摩诘杀怪最少攻略,20分钟轻松做完!
  13. 上下协同,用友IPD的研发管理之道(下)
  14. □ 影片名:《樱桃小丸子》(36004) 在线播放
  15. HDMI转换芯片——MS1858
  16. 【解决Hibernate异常 identifier of an instance of xxx(实体类) was altered from xxx to xxxPK】
  17. 我的面试题. 业务抽象能力测试.
  18. 验证:获取linux系统的网卡信息
  19. php技术创新:利用动态404页面实现全站自动静态化
  20. 汉语言文学专业c学校,自考汉语言文学专业哪个学校好?

热门文章

  1. webpack vue router import() 打包后单个js文件名称自定义
  2. 【Python爬虫】网络爬虫的“盗亦有道”
  3. 图表 stack属性_想快速了解MEAN Stack吗? 这是带有有用图表的文档。
  4. 构建服务器_如何使用无服务器构建完整的后端系统
  5. 头脑风暴算法代码_混乱的头脑导致混乱的代码
  6. go rpc安装方法
  7. C语言:斗地主发牌程序
  8. 如何用 Python 实现超级玛丽的人物行走和碰撞检测?
  9. Spark在文本统计中的简单应用
  10. Hadoop 系列之 1.0 和2.0 架构