将自己写的Python代码打包放到PyPI上
如果是开源的Python代码,为了能够让大家更方便的使用,放到PyPI上也许是个非常不错的主意(PyPI:Python Package Index)。刚开始我以为要将代码打包放到PyPI上是一件非常复杂繁琐的事情,不过看过《Dive Into Python 3》的PACKAGING PYTHON LIBRARIES介绍(CHAPTER 16),并自己动手操作了一下,发现打包发布这个事情并没有想象中的那么有难度。为了方便其他朋友阅读的方便,就尝试写了这个博文,来记录下如何将自己写的Python代码打包上传到PyPI上。
在Python的世界里,有个叫Distutils的工具模块可以帮我们轻松的解决这个问题,既然这样,让我们开始打包之旅吧。
要打包代码,首先你的确保你的代码得是个包。比如,你写了一些功能的代码块,为了方便引用,你就需要将代码变成一个包,下次需要使用的时候,直接引用这个包里面的某个具体功能就好了。在Python中,要将这些代码变成包非常容易,你的这些功能的合集,可以用一个你觉得合适的名称来命名,创建这个命名的文件夹,并在文件夹下创建一个__init__.py
文件,剩余的就是将你这些代码放入到这个文件夹下面即可。整理成包的文件结构大概像下面这样:
- somefunctions/
- |
- +-- __init__.py
- |
- +-- myscripts1.py
- |
- +-- mysscripts2.py
- |
- +-- mymorescripts.py
- |
somefunctions
就是你包的名称,下面my***.py
的各种文件就是你原有的各种代码模块。是不是很简单就将自己的代码变成了包?确实很简单,你这步就是新建一个文件夹,把文件全放进去而已——哦,还有添加个__init__.py
文件(文件内容可以为空).
到这里,我们已经有Python包了,如果不传到PyPI上的话,你都可以直接用了,最直接的方法是将这个文件夹拷到你的项目目录下,然后在项目代码里,你大概就能引用它了:
1
2
3
4
5
|
import somefunctions module = somefunctions.myscripts1 ### 这里你就可以调用myscripts1里面的功能了. |
当然,我们的目标是打包到PyPI上,而不是将这个包拷来拷去的,后面安装一下,引用起来将更加的方便。
好了,既然要放到PyPI上,那么我们就需要在上面的基础上,在加点料。首先,我们需要调整下文件的目录结构,把上面的改成下面这个样子:
- somefunctions/
- |
- +-- somefunctions/
- . |
- . +-- __init__.py
- . |
- . +-- myscripts1.py
- . |
- . +-- mysscripts2.py
- . |
- . +-- mymorescripts.py
- . |
- .
- |
就是将原来的目录深移一层,文件夹名称一样即可。这步也不难吧。好吧,然后在到第一层的目录下创建些特殊文件,具体你可以看看下面这个文件结构你就明白了:
- somefunctions
- |
- +-- COPYING.txt
- |
- +-- README.txt
- |
- +-- setup.py
- |
- +-- somefunctions
- . |
- . +-- __init__.py
- . |
- . +-- myscripts1.py
- . |
- . +-- mysscripts2.py
- . |
- . +-- mymorescripts.py
- . |
- .
- |
- +-- docs/
- |
哇,咋一看,变了好多啊,其实不多,解释下:
TIPS:
- COPYING.txt 就是授权文件,里面是你关于这个包的授权,比如:MIT license,那么你里面放入MIT License全文即可,当然,如果你不清楚这个,你完全可以不要这个文件。
- README.txt,这个文件想必研发都应该清楚。如果有,尽量放些东西在这里了,后面如果可能我们会用到它的。需要注意的是,Windows的回车和Linux不一样,所以建议用Windows的好了。另外你也可以使用
README.rst
这类文件表示(reStructuredText文件,如果不清楚可以参看我前面几篇文章:入门,Emacs快捷键) - setup.py,核心文件,这里面的内容马上我们会讲。
- docs/,这个文件夹你放你的documents吧,不过要用心写文档真是个难事,所以这个文件夹基本是不存在的——为自己的懒惰可耻一把。
- 如果的包整个就一个文件,那么你也完全可以不用考虑再建一层目录了,直接放到README文件所在目录下就可以了,虽然我不建议这么操作。
好了,文件都建好了,再来进化下,我们为setup.py
填上内容,让我们的setup.py
真正的能用起来,注意哦,前面没distutils什么事情,他的作用在这里哦。放出一个setup.py
的Demo:
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
import codecs import os import sys try : from setuptools import setup except : from distutils.core import setup """ 打包的用的setup必须引入, """ def read(fname): """ 定义一个read方法,用来读取目录下的长描述 我们一般是将README文件中的内容读取出来作为长描述,这个会在PyPI中你这个包的页面上展现出来, 你也可以不用这个方法,自己手动写内容即可, PyPI上支持.rst格式的文件。暂不支持.md格式的文件,<BR>.rst文件PyPI会自动把它转为HTML形式显示在你包的信息页面上。 """ return codecs. open (os.path.join(os.path.dirname(__file__), fname)).read() NAME = "somefunctions" """ 名字,一般放你包的名字即可 """ PACKAGES = [ "somefunctions" ,] """ 包含的包,可以多个,这是一个列表 """ DESCRIPTION = "this is a test package for packing python liberaries tutorial." """ 关于这个包的描述 """ LONG_DESCRIPTION = read( "README.rst" ) """ 参见read方法说明 """ KEYWORDS = "test python package" """ 关于当前包的一些关键字,方便PyPI进行分类。 """ AUTHOR = "MitchellChu" """ 谁是这个包的作者,写谁的名字吧 我是MitchellChu,自然这里写的是MitchellChu """ AUTHOR_EMAIL = "youremail@email.com" """ 作者的邮件地址 """ """ 你这个包的项目地址,如果有,给一个吧,没有你直接填写在PyPI你这个包的地址也是可以的 """ VERSION = "1.0.1" """ 当前包的版本,这个按你自己需要的版本控制方式来 """ LICENSE = "MIT" """ 授权方式,我喜欢的是MIT的方式,你可以换成其他方式 """ setup( name = NAME, version = VERSION, description = DESCRIPTION, long_description = LONG_DESCRIPTION, classifiers = [ 'License :: OSI Approved :: MIT License' , 'Programming Language :: Python' , 'Intended Audience :: Developers' , 'Operating System :: OS Independent' , ], keywords = KEYWORDS, author = AUTHOR, author_email = AUTHOR_EMAIL, url = URL, license = LICENSE, packages = PACKAGES, include_package_data = True , zip_safe = True , ) ## 把上面的变量填入了一个setup()中即可。 |
你如果需要写一个setup.py
文件,但又不会写,没关系,上面的复制一下,把信息改成你的,而后直接保存就可以了。Easy way to do this。
TIPS:
- 文中的
classifiers
的内容并不是随便填写的,你需要参照本文参考文档中的PyPI Classifiers来写。 setup.py
就是个Python代码,在这里面理论上你可以做任何Python能够做的事情,不过,为了保证正确性和简洁,我建议尽量少些复杂代码,毕竟就是个大包的代码,搞得太复杂了反而不好。- 一般情况下,Distutils只会包含你包文件夹内的:
README.txt
,setup.py
,packages
里面定义的所有某块的.py文件,py_modules
参数包含的所有.py文件,其他文件需要被包含进来,需要单独添加。需要添加,你可以在根目录添加一个MANIFEST.in
文件,将要包含的文件放入,具体规则请参考官方文档格式。如我们这里需要添加COPYING.txt
可以在MANIFEST.in
中添加如下行:- include COPYING.txt
setup.py
写完之后,为了保证效果,我们可以检查下,当然不是让你去读代码,因为我们写的这些东西是要给Distutils看的,所以用它来检查最合适不过了,在命令行下输入:
1
2
3
4
5
6
7
|
## 直接路由到你写的setup.py文件的更目录下 ## 然后运行: python setup.py check ## 输出一般是running check ## 如果有错误或者警告,就会在此之后显示 ## 没有任何显示表示Distutils认可你这个setup.py文件。 |
如果有错误输出,按照显示进行修改即可,到没有任何异常输出的时候,你就可以开始创建你的源码分发包了。打包也仅仅是个命令而已:
1
2
3
4
5
6
7
8
9
10
|
## 和上面一样,路由到setup.py所在目录 ## 也是使用setup.py本身代码来运行 ## 不同的是后面的参数不一样。 python setup.py sdist ## 命令执行后会输出打包的状态,你可以进行查看 ## 如果有warning的话,你可以稍后返回修改对应的地方后,重新打包 ## 如果正常的情况下,你应该可以在你的根目录下看到一个dist/的文件夹 ## 文件夹里面包含了当前打包出来的一个.zip文件。或者.tar.gz文件. |
一路下来,我们获得了可以分发的包了,接下来,我们要做的就是将这个包放到PyPI上去了。
我们在做这步前,建议你先到PyPI上注册个帐号,这样方便些,当然,你也可以不注册,后面的步骤中会有提示,根据提示进行也可以。——本文按照先在PyPI上注册过帐号的方式进行。
我们有了PyPI的帐号,那么我们开始吧,离成功仅一步之遥了。在你包的根目录下,运行下面的Shell命令:
1
2
3
|
## 注册,并上传sdist python setup.py register sdist upload |
系统会提示类似下面信息:
- running register
- We need to know who you are, so please choose either:
- 1. use your existing login,
- 2. register as a new user,
- 3. have the server generate a new password for you (and email it to you), or
- 4. quit
- Your selection [default 1]: 1
恩,如果你没有帐号,在这一步选择2吧,我们不二了,分道扬镳鸟,选择1,回车根据提示输入用户名和密码,接着就等待处理。
- Registering somefunctions to http://pypi.python.org/pypi
- Server response (200): OK
- running sdist
- ... output trimmed for brevity ...
- running upload
- Submitting dist\somefunctions.tar.gz to http://pypi.python.org/pypi
- Server response (200): OK
- I can store your PyPI login so future submissions will be faster.
- (the login will be stored in ~/.pypirc)
- Save your login (y/N)?n
当你看到上面这种信息的时候,说明已经完成了上传工作,这个时候你的包就在PyPI上了。
TIPS:
- 可能上传的过程出现问题,这个时候你需要终止当前过程,之后到PyPI上查看,如果已经有了这个包,你需要删除(建议操作),或者你重新编译(用新的版本号)在上传
- 最后问你要不要保存你的帐号信息,你可以选择y/n,y的话,在你的用户根目录下会有个
.pypirc
文件,里面有你账户的明文信息。
包到这里,就完成了上传PyPI的工作了。你如果要用,安装下就好:
1
|
pip install somefunctions |
这个时候,你在你新的项目中只要直接import就可以了
1
2
3
4
5
|
import somefunctions ## Or from somefunctions import modulename |
到此就结束了,是不是感觉很简单?
后记:
本文是Mitchell Chu根据自己打包的经历写的一篇入门文章,由于本人也是刚刚开始使用,难免会有错谬之处,还请指正。另,文中仅仅是打包成压缩包的形式,还有编译成可执行文件的发布方式这里没有,有此需要的请参考文后的参考文档。
将自己写的Python代码打包放到PyPI上的更多相关文章
- windows环境下把Python代码打包成独立执行的exe
windows环境下把Python代码打包成独立执行的exe可执行文件 有时候因为出差,突然急需处理一批数据.虽然写好的脚本存储在云端随用随取,然而编译的环境还需要重新搭建,模块也需要重新装载,从 ...
- 我写的python代码的规则
1.Python文件的命名: 采用每个单词的首字母大写,不使用下划线 2.Python类的命名: 采用每个单词的首字母大写,不使用下划线 3.Python包名的命名:采用每个单词都是小写,不使用下划线 ...
- 手写算法-python代码实现KNN
原理解析 KNN-全称K-Nearest Neighbor,最近邻算法,可以做分类任务,也可以做回归任务,KNN是一种简单的机器学习方法,它没有传统意义上训练和学习过程,实现流程如下: 1.在训练数据 ...
- 【MaixPy3文档】写好 Python 代码!
本文是给有一点 Python 基础但还想进一步深入的同学,有经验的开发者建议跳过. 前言 上文讲述了如何认识开源项目和一些编程方法的介绍,这节主要来说说 Python 代码怎么写的一些演化过程和可以如 ...
- 我写的 Python 代码,同事都说好
原文链接: 我写的 Python 代码,同事都说好 人生苦短,我用 Python. 程序员的追求就是不写代码,早日财务自由.不对,一不小心把实话说出来了,应该是将代码写得简洁,优雅. Python 程 ...
- 将python代码打包成一个app/exe
前言 打包的代码通常都需要写一个简单的界面,一般用PyQt来写.用PyQt写界面的方法请戳这里:PyQt5的安装及基本配置 PyQt5教程 python提供了几个用来打包的模块,主要有py2ap ...
- python代码打包发布
背景 本文介绍了python中一种最简单的代码结构的打包方式 包名称 我们先给我们的包取个名字,python包起名需要符合下面的规范 全部小写 在pypi上是唯一的 下划线分隔或没有单词分隔符(不要使 ...
- 如何优雅的写好python代码?
Python与其他语言(比如 java或者 C ++ )相比有较大的区别,其中最大的特点就是非常简洁,如果按照其他语言的思路老师写Python代码,则会使得代码繁琐复杂,并且容易出现bug,在Pyth ...
- 不写1行代码,在Mac上体验ASP.NET 5的最简单方法
昨天微软发布了ASP.NET 5 beta2(详见ASP.NET 5 Beta2 发布),对ASP.NET 5的好奇心又被激发了. 今天下午在Mac OS X上体验了一下ASP.NET 5,而且借助Y ...
随机推荐
- python 代码片段5
#coding=utf-8 # python 有两个主要数据类型:int和float.根据Kiss原则,python只有一宗整数类型int. print 3**3 print int('123') p ...
- Storm Grouping —— 流分组策略
Storm Grouping: Shuffle Grouping :随机分组,尽量均匀分布到下游Bolt中 将流分组定义为混排.这种混排分组意味着来自Spout的输入将混排,或随机分发给此Bolt中的 ...
- BZOJ3676 [Apio2014]回文串
Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行 ...
- Linux_屏蔽360、scanv、QQ管家等IP扫描
vi banip.sh #!/bin/bash echo "banip" iptables -A INPUT -s 221.204.203.0/24 -j DROP iptable ...
- C#引用Interop.SQLDMO.dll后的注意事项(转)
C#引用sqldmo.dll的方法 找到 sqldmo.dll这个文件C:\Program Files\Microsoft SQL Server\80\Tools\Binn\sqldmo.dll用.N ...
- Android使用AsyncTask实现可以断点续传的DownloadManager功能
http://www.it165.net/pro/html/201211/4210.html 最近做项目卡壳了,要做个Android的应用市场,其他方面都还好说,唯独这个下载管理算是给我难住了,究其原 ...
- 不用逗号进行UNION
./download.php ...if($link){ //加密后ID$link = base64_decode(urldecode($link));$link_array = explode ...
- MySQL 5.7在线设置复制过滤
很久没有更新博客了,主要是公司事情比较多,最近终于闲下来了.然而5.7也GA了,有许多新的特性,其中现在可以进行在线设置复制过滤了.但是还是得停复制,不过不用重启实例了.方便了DBA们进行临时性的调整 ...
- TabBarViewController的创建以及渐变隐藏
// CustomTabBarViewController.h #import <UIKit/UIKit.h> @interface CustomTabBarViewController ...
- [SHELL进阶] (转)最牛B的 Linux Shell 命令 (四)
1.查看ASCII码表 man 7 ascii 很多人初学编程都会接触到ascii码的概念,有时候为了查某个符号的ascii值,可能还得翻箱倒柜找出当年的课本?Linux Manpage里面其实包含 ...