亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Python打包系統(tǒng)簡(jiǎn)單入門

ls0609 / 809人閱讀

摘要:所以這篇文章就來(lái)研究一下自帶的打包系統(tǒng)。打包項(xiàng)目下面就進(jìn)入本文的正題,的打包系統(tǒng)上?;旧衔覀儾恍枰耆私獯虬到y(tǒng),只要學(xué)會(huì)簡(jiǎn)單的幾個(gè)點(diǎn)就可以打包自己的類庫(kù)了。版本號(hào)下面是開發(fā)測(cè)測(cè)發(fā)布候選最終發(fā)布等情況的版本號(hào)實(shí)例。

最近把pyenv、pipenv這種都研究了一下,然后我發(fā)現(xiàn)一個(gè)嚴(yán)重的問(wèn)題:就是我雖然看了半天這些工具,但是我對(duì)Python自己的打包系統(tǒng)卻完全沒(méi)有了解。所以這篇文章就來(lái)研究一下Python自帶的打包系統(tǒng)。

pip

先來(lái)詳細(xì)介紹一下pip的用法,平時(shí)基本上我們用pip的時(shí)候也就是一個(gè)pip install。其實(shí)pip也有很多特性,在此先介紹一下常用的一些特性。此部分參考了pip文檔,想了解更多的話可以看原文。

安裝

最常用的命令就是安裝了,除此以外還可以指定版本號(hào):

$ pip install SomePackage            # 不指定版本號(hào),安裝最新版
$ pip install SomePackage==1.0.4     # 指定版本號(hào)
$ pip install "SomePackage>=1.0.4"     # 指定最小版本號(hào)

$ pip install -r requirements.txt # 從需求文件安裝
$ pip install -e . # 從本地項(xiàng)目setup.py安裝
使用代理服務(wù)器

當(dāng)從官方的PyPI源安裝比較慢的時(shí)候,可以考慮使用代理服務(wù)器,指定代理服務(wù)器的方法有三種:

使用--proxy參數(shù)在命令行指定,代理格式為[user:passwd@]proxy.server:port。

在配置文件中指定。

設(shè)置http_proxy, https_proxyno_proxy環(huán)境變量。

使用需求文件(requirements.txt)

在需要很多pip包的項(xiàng)目中,用pip一個(gè)個(gè)安裝包不是一個(gè)好辦法,這時(shí)候可以考慮使用需求文件。

如果要生成需求文件,用下面的命令。這會(huì)將當(dāng)前Python環(huán)境中的所有包的當(dāng)前版本狀態(tài)保存下來(lái),將來(lái)安裝的時(shí)候會(huì)精確還原到凍結(jié)的那個(gè)狀態(tài)。

pip freeze > requirements.txt

要從需求文件中安裝,則是用下面的命令:

pip install -r requirements.txt

官方文檔還給出了一個(gè)帶注釋的實(shí)例需求文件:

#
####### example-requirements.txt #######
#
###### 沒(méi)有版本標(biāo)識(shí)符的包,會(huì)安裝最新版 ######
nose
nose-cov
beautifulsoup4
#
###### 帶版本標(biāo)識(shí)符的包 ######
#  版本標(biāo)識(shí)符的資料 https://www.python.org/dev/peps/pep-0440/#version-specifiers
docopt == 0.6.1             # Version Matching. Must be version 0.6.1
keyring >= 4.1.1            # Minimum version 4.1.1
coverage != 3.5             # Version Exclusion. Anything except version 3.5
Mopidy-Dirble ~= 1.1        # Compatible release. Same as >= 1.1, == 1.*
#
###### 還可以指定其他的需求文件 ######
-r other-requirements.txt
#
#
###### 還可以指定本地貨網(wǎng)絡(luò)上的特定包 ######
./downloads/numpy-1.9.2-cp34-none-win32.whl
http://wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev1820+49a8884-cp34-none-win_amd64.whl
#
###### Additional Requirements without Version Specifiers ######
#   和第一部分一樣,這里這些部分沒(méi)有順序需求,可以隨意改變位置
rejected
green
#

版本標(biāo)識(shí)符用來(lái)指定包的版本,有以下幾個(gè)例子:

SomeProject
SomeProject == 1.3
SomeProject >=1.2,<.2.0
SomeProject[foo, bar]
SomeProject~=1.4.2

從6.0版本開始,pip也支持環(huán)境標(biāo)記(也就是分號(hào)后面跟Python版本或者系統(tǒng)類型):

SomeProject ==5.4 ; python_version < "2.7"
SomeProject; sys_platform == "win32"
卸載

卸載某個(gè)包使用下面的命令:

$ pip uninstall SomePackage
列出包

要列出所有已安裝的包:

$ pip list
docutils (0.9.1)
Jinja2 (2.6)
Pygments (1.5)
Sphinx (1.1.2)

要列出過(guò)時(shí)的包:

$ pip list --outdated
docutils (Current: 0.9.1 Latest: 0.10)
Sphinx (Current: 1.1.2 Latest: 1.1.3)

要列出某個(gè)已安裝的包的詳細(xì)信息:

$ pip show sphinx
---
Name: Sphinx
Version: 1.1.3
Location: /my/env/lib/pythonx.x/site-packages
Requires: Pygments, Jinja2, docutils
搜索

要搜索一個(gè)包,用下面的命令,搜索結(jié)果可能有很多:

$ pip search "query"
更新

要更新一個(gè)包,使用-U或者--upgrade參數(shù):

pip install -U 

如果想更新所有的包,很遺憾,pip并沒(méi)有提供該功能,我在StackOverFlow上找到一個(gè)看起來(lái)比較簡(jiǎn)單的解決辦法,就是在Python解釋器中執(zhí)行下面的代碼:

import pkg_resources
from subprocess import call

packages = [dist.project_name for dist in pkg_resources.working_set]
call("pip install --upgrade " + " ".join(packages), shell=True)

以上就是pip的一些簡(jiǎn)單用法,詳情可參考官方文檔。

打包項(xiàng)目

下面就進(jìn)入本文的正題,Python的打包系統(tǒng)上?;旧衔覀儾恍枰耆私獯虬到y(tǒng),只要學(xué)會(huì)簡(jiǎn)單的幾個(gè)點(diǎn)就可以打包自己的類庫(kù)了。打包需要distutils、setuptools、wheel等類庫(kù),不過(guò)基本上我們只需要寫好其中最重要的setup.py,就可以完成打包工作了。distutils是官方的類庫(kù),在當(dāng)年有很廣泛的使用,不過(guò)到了現(xiàn)在很難用。distutuils類庫(kù)的核心就是setup函數(shù),我們需要將項(xiàng)目的各種信息作為參數(shù)傳遞給setup函數(shù),然后就可以用相關(guān)命令創(chuàng)建項(xiàng)目分發(fā)包了。關(guān)于distutils的用法,可以參考官方文檔。

當(dāng)然現(xiàn)在項(xiàng)目基本都不用distutils了,有更好用的第三方替代品,那就是setuptools,它可以算作是distutils的加強(qiáng)版,功能更加強(qiáng)大、使用更加簡(jiǎn)單,這就是這里要介紹的。其實(shí)從文檔就可以看出來(lái),distutils畢竟時(shí)間比較早,有些接口設(shè)計(jì)的不太合理甚至有些反人類,setuptools的文檔就簡(jiǎn)單多了。

準(zhǔn)備項(xiàng)目

為了做演示,首先需要準(zhǔn)備一個(gè)項(xiàng)目,一個(gè)項(xiàng)目應(yīng)該包括README和LICENSE等文件,README文件是Markdown格式的文本文件,用于描述項(xiàng)目自身;LICENSE文件是授權(quán)文件,列出項(xiàng)目使用者應(yīng)該遵循的各種條款。下圖是我的項(xiàng)目結(jié)構(gòu)。

此外還可能存在幾個(gè)文件:

setup.cfg。對(duì)應(yīng)的配置文件,一般情況下可以不要。

MANIFEST.in。清單文件,當(dāng)項(xiàng)目中需要一些沒(méi)辦法自動(dòng)包括到源代碼分發(fā)包的文件時(shí),可能需要用到它。

具體文件內(nèi)容就不列出了。需要注意my_package/__init__.py文件中應(yīng)該有如下一行標(biāo)識(shí)包名:

name = "yitian_first_package"
編寫setup.py文件

用setuptools來(lái)編寫setup.py文件是一件非常簡(jiǎn)單的事情,而且有很多例子可供參考,我挑選了Kenneth Reitz(requests、pipenv等類庫(kù)的作者)寫的例子,做了一些修改并翻譯了一些注釋:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 注意 如果要使用上傳功能,需要安裝twine包:
#   $ pip install twine

import io
import os
import sys
from shutil import rmtree

from setuptools import find_packages, setup, Command

# 包的元信息
NAME = "yitian_first_package"
DESCRIPTION = "項(xiàng)目的簡(jiǎn)短描述,不超過(guò)200字符"
URL = "https://github.com/techstay/python-study"
EMAIL = "lovery521@gmail.com"
AUTHOR = "易天"
REQUIRES_PYTHON = ">=3.6.0"
VERSION = "0.1.0"
KEYWORDS = "sample setuptools development"

# 項(xiàng)目依賴,也就是必須安裝的包
REQUIRED = [
    "requests-html"
]

# 項(xiàng)目的可選依賴,可以不用安裝
EXTRAS = {
    # "fancy feature": ["django"],
}

# 剩下部分不用怎么管 :)
# ------------------------------------------------
# 除了授權(quán)和授權(quán)文件標(biāo)識(shí)符!
# 如果你改了License, 記得也相應(yīng)修改Trove Classifier!

here = os.path.abspath(os.path.dirname(__file__))

# 導(dǎo)入README文件作為項(xiàng)目長(zhǎng)描述.
# 注意 這需要README文件存在!
try:
    with io.open(os.path.join(here, "README.md"), encoding="utf-8") as f:
        long_description = "
" + f.read()
except FileNotFoundError:
    long_description = DESCRIPTION

# 當(dāng)前面沒(méi)指定版本號(hào)的時(shí)候,將包的 __version__.py 模塊加載進(jìn)來(lái)
about = {}
if not VERSION:
    with open(os.path.join(here, NAME, "__version__.py")) as f:
        exec(f.read(), about)
else:
    about["__version__"] = VERSION


class UploadCommand(Command):
    """上傳功能支持"""

    description = "Build and publish the package."
    user_options = []

    @staticmethod
    def status(s):
        """Prints things in bold."""
        print("