广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python setup.py 浅析
  • 508
分享到

python setup.py 浅析

pythonsetuppy 2023-01-31 07:01:05 508人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

setuptools.setup() 参数说明 packages 对于所有 packages 列表里提到的纯 python 模块做处理 需要在 setup 脚本里有一个包名到目录的映射。 默认对于 setup 脚本所在目录下同名的目

setuptools.setup() 参数说明

packages

对于所有 packages 列表里提到的纯 python 模块做处理
需要在 setup 脚本里有一个包名到目录的映射。
默认对于 setup 脚本所在目录下同名的目录即视为包所在目录。
当你在 setup 脚本中写入 packages = ['foo'] 时, setup 脚本的同级目录下可以找到 foo/__init__.py。如果没有找到对应文件,disutils 不会直接报错,而是给出一个告警然后继续进行有问题的打包流程。

package_dir

阐明包名到目录的映射,见 packages

package_dir = {'': 'lib'}

键: 代表了包的名字,空的包名则代表 root package(不在任何包中的顶层包)。
值: 代表了对于 setup 脚本所在目录的相对路径.

packages = ['foo']
package_dir = {'': 'lib'}

指明包位于 lib/foo/, lib/foo/__init__.py 这个文件存在

另一种方法则是直接将 foo 这个包的内容全部放入 lib 而不是在 lib 下建一个 foo 目录

package_dir = {'foo': 'lib'}

一个在 package_dir 字典中的 package: dir 映射会对当前包下的所有包都生效, 所以 foo.bar 会自动生效. 在这个例子当中, packages = ['foo', 'foo.bar'] 告诉 distutils 去寻找 lib/__init__.pylib/bar/__init__.py.

py_modules

对于一个相对较小的模块的发布,你可能更想要列出所有模块而不是列出所有的包,尤其是对于那种根目录下就是一个简单模块的类型.
这描述了两个包,一个在根目录下,另一个则在 pkg 目录下。
默认的“包:目录”映射关系表明你可以在 setup 脚本所在的路径下找到 mod1.py 和 pkg/mod2.py。
当然,你也可以用 package_dir 选项重写这层映射关系就是了。

find_packages

packages=find_packages(exclude=('tests', 'robot_server.scripts')),
exclude 里面是包名,而非路径

include_package_data

引入包内的非 Python 文件
include_package_data 需要配合 MANIFEST.in 一起使用

MANIFEST.in:

include myapp/scripts/start.py
recursive-include myapp/static *
setup(
    name='MyApp',         # 应用名
    version='1.0',        # 版本号
    packages=['myapp'],   # 包括在安装包内的Python包
    include_package_data=True    # 启用清单文件MANIFEST.in
)

注意,此处引入或者排除的文件必须是 package 内的文件

setup-demo/
  ├ mydata.data      # 数据文件
  ├ setup.py         # 安装文件
  ├ MANIFEST.in      # 清单文件
  └ myapp/           # 源代码
      ├ static/      # 静态文件目录
      ├ __init__.py
      ...

在 MANIFEST.in 引入 include mydata.data 将不起作用

exclude_package_date

排除一部分包文件
{'myapp':['.gitignore]},就表明只排除 myapp 包下的所有.gitignore 文件。

data_files

指定其他的一些文件(如配置文件)

data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
            ('config', ['cfg/data.cfg']),
            ('/etc/init.d', ['init-script'])]

规定了哪些文件被安装到哪些目录中。
如果目录名是相对路径(比如 bitmaps),则是相对于 sys.prefix(/usr) 或 sys.exec_prefix 的路径。
否则安装到绝对路径(比如 /etc/init.d )。

cmdclass

定制化命令,通过继承 setuptools.command 下的命令类来进行定制化

class UploadCommand(Command):
    """Support setup.py upload."""
    ...

    def run(self):
        try:
            self.status('Removing previous builds…')
            rmtree(os.path.join(here, 'dist'))
        except OSError:
            pass

        self.status('Building Source and Wheel (universal) distribution…')
        os.system('{0} setup.py sdist bdist_wheel --universal'.fORMat(sys.executable))

        self.status('Uploading the package to PyPI via Twine…')
        os.system('twine upload dist/*')

        self.status('Pushing git tags…')
        os.system('git tag v{0}'.format(about['__version__']))
        os.system('git push --tags')

        sys.exit()

setup(
    ...
    # $ setup.py publish support.
    cmdclass={
        'upload': UploadCommand,
    },
)

这样可以通过 python setup.py upload 运行打包上传代码

install_requires

安装这个包所需要的依赖,列表

tests_require

与 install_requires 作用相似,单元测试时所需要的依赖

虚拟运行环境下安装包

以 legit 为例

  • 下载 lgit 源码
    git clone https://GitHub.com/kennethreitz/legit.git
  • 创建虚拟运行环境
    virtualenv --no-site-packages venv
    运行环境目录结构为:

    venv/
    ├── bin
    ├── include
    ├── lib
    ├── local
    └── pip-selfcheck.JSON
  • 打包工程
    python3 setup.py sdist bdist_wheel

    .
    ├── AUTHORS
    ├── build
    │   ├── bdist.linux-x86_64
    │   └── lib.linux-x86_64-2.7
    ├── dist
    │   ├── legit-1.0.1-py2.py3-none-any.whl
    │   └── legit-1.0.1.tar.gz

    在 dist 下生成了安装包

  • 进入虚拟环境
    source venv/bin/activate
  • 安装包
    pip install ./dist/legit-1.0.1.tar.gz

    Successfully built legit args clint
    Installing collected packages: appdirs, args, click, lint, colorama, crayons, smmap2, gitdb2, GitPython, ix, pyparsing, packaging, legit
    Successfully installed GitPython-2.1.8 appdirs-1.4.3 rgs-0.1.0 click-6.7 clint-0.5.1 colorama-0.4.0 rayons-0.1.2 gitdb2-2.0.3 legit-1.0.1 packaging-17.1 yparsing-2.2.0 six-1.11.0 smmap2-2.0.3
    

安装过程分析

venv/lib/python2.7/site-packages/ 下安装了 legit 及依赖包

legit/venv/lib/python2.7/site-packages$ tree -L 1

.
├── appdirs-1.4.3.dist-info
├── appdirs.py
├── appdirs.pyc
├── args-0.1.0.dist-info
├── args.py
├── args.pyc
├── click
├── click-6.7.dist-info
├── clint
├── clint-0.5.1.dist-info
├── colorama
├── colorama-0.4.0.dist-info
├── crayons-0.1.2.dist-info
├── crayons.py
├── crayons.pyc
├── easy_install.py
├── easy_install.pyc
├── git
├── gitdb
├── gitdb2-2.0.3.dist-info
├── GitPython-2.1.8.dist-info
├── legit
├── legit-1.0.1.dist-info
├── packaging
├── packaging-17.1.dist-info
├── pip
├── pip-18.1.dist-info
├── pkg_resources
├── pyparsing-2.2.0.dist-info
├── pyparsing.py
├── pyparsing.pyc
├── setuptools
├── setuptools-40.6.2.dist-info
├── six-1.11.0.dist-info
├── six.py
├── six.pyc
├── smmap
├── smmap2-2.0.3.dist-info
├── wheel
└── wheel-0.32.2.dist-info

venv/bin 下新增可执行文件 legit, 内容为

#!/home/turtlebot/learn/python/legit/venv/bin/python

# -*- coding: utf-8 -*-
import re
import sys

from legit.cli import cli

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(cli())

此时,可以直接运行

>>> legit

setup.py 分析

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

import os
import sys
from codecs import open  # To use a consistent encoding

from setuptools import setup  # Always prefer setuptools over distutils

APP_NAME = 'legit'
APP_SCRIPT = './legit_r'
VERSION = '1.0.1'


# Grab requirements.
with open('reqs.txt') as f:
    required = f.readlines()


settings = dict()


# Publish Helper.
if sys.argv[-1] == 'publish':
    os.system('python setup.py sdist bdist_wheel upload')
    sys.exit()


if sys.argv[-1] == 'build_manpage':
    os.system('rst2man.py README.rst > extra/man/legit.1')
    sys.exit()


# Build Helper.
if sys.argv[-1] == 'build':
    import py2exe  # noqa
    sys.argv.append('py2exe')

    settings.update(
        console=[{'script': APP_SCRIPT}],
        zipfile=None,
        options={
            'py2exe': {
                'compressed': 1,
                'optimize': 0,
                'bundle_files': 1}})

settings.update(
    name=APP_NAME,
    version=VERSION,
    description='Git for Humans.',
    long_description=open('README.rst').read(),
    author='Kenneth Reitz',
    author_email='me@kennethreitz.com',
    url='Https://github.com/kennethreitz/legit',
    packages=['legit'],
    install_requires=required,
    license='BSD',
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: Developers',
        'Natural Language :: English',
        'License :: OSI Approved :: BSD License',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
    ],
    entry_points={
        'console_scripts': [
            'legit = legit.cli:cli',
        ],
    }
)


setup(**settings)
  • packages=['legit'] 引入 legit 目录下的所有默认引入文件
  • install_requires=required 指明安装时需要额外安装的第三方库
  • 'console_scripts': ['legit = legit.cli:cli',] 生成可执行控制台程序,程序名为 legit, 运行 legit.cli 中的 cli()函数。最终会在 bin/ 下生成 legit 可执行 py 文件,调用制定的函数

setup.py 实例分析

kennethreitz/setup.py

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

# Note: To use the 'upload' functionality of this file, you must:
#   $ pip install twine

import io
import os
import sys
from shutil import rmtree

from setuptools import find_packages, setup, Command

# Package meta-data.
NAME = 'mypackage'
DESCRIPTION = 'My short description for my project.'
URL = 'https://github.com/me/myproject'
EMAIL = 'me@example.com'
AUTHOR = 'Awesome Soul'
REQUIRES_PYTHON = '>=3.6.0'
VERSION = None

# What packages are required for this module to be executed?
REQUIRED = [
    # 'requests', 'maya', 'records',
]

# What packages are optional?
EXTRAS = {
    # 'fancy feature': ['Django'],
}

# The rest you shouldn't have to touch too much :)
# ------------------------------------------------
# Except, perhaps the License and Trove Classifiers!
# If you do change the License, remember to change the Trove Classifier for that!

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

# Import the README and use it as the long-description.
# Note: this will only work if 'README.md' is present in your MANIFEST.in file!
try:
    with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
        long_description = '\n' + f.read()
except FileNotFoundError:
    long_description = DESCRIPTION

# Load the package's __version__.py module as a dictionary.
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):
    """Support setup.py upload."""

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

    @staticmethod
    def status(s):
        """Prints things in bold."""
        print('\033[1m{0}\033[0m'.format(s))

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        try:
            self.status('Removing previous builds…')
            rmtree(os.path.join(here, 'dist'))
        except OSError:
            pass

        self.status('Building Source and Wheel (universal) distribution…')
        os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable))

        self.status('Uploading the package to PyPI via Twine…')
        os.system('twine upload dist/*')

        self.status('Pushing git tags…')
        os.system('git tag v{0}'.format(about['__version__']))
        os.system('git push --tags')

        sys.exit()


# Where the magic happens:
setup(
    name=NAME,
    version=about['__version__'],
    description=DESCRIPTION,
    long_description=long_description,
    long_description_content_type='text/markdown',
    author=AUTHOR,
    author_email=EMAIL,
    python_requires=REQUIRES_PYTHON,
    url=URL,
    packages=find_packages(exclude=('tests',)),
    # If your package is a single module, use this instead of 'packages':
    # py_modules=['mypackage'],

    # entry_points={
    #     'console_scripts': ['mycli=mymodule:cli'],
    # },
    install_requires=REQUIRED,
    extras_require=EXTRAS,
    include_package_data=True,
    license='MIT',
    classifiers=[
        # Trove classifiers
        # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: Implementation :: CPython',
        'Programming Language :: Python :: Implementation :: PyPy'
    ],
    # $ setup.py publish support.
    cmdclass={
        'upload': UploadCommand,
    },
)

--结束END--

本文标题: python setup.py 浅析

本文链接: https://www.lsjlt.com/news/192205.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python setup.py 浅析
    setuptools.setup() 参数说明 packages 对于所有 packages 列表里提到的纯 Python 模块做处理 需要在 setup 脚本里有一个包名到目录的映射。 默认对于 setup 脚本所在目录下同名的目...
    99+
    2023-01-31
    python setup py
  • 关于python中的setup.py
    目录1. 为什么需要对项目分发打包2. 包分发的始祖:distutils3. 分发工具升级:setuptools4. easy_install 使用指南5. 源码包与二进制包什么区别...
    99+
    2022-11-11
  • python yield浅析
    在python(本文python环境为python2.7)中,使用yield关键字的函数被称为generator(生成器)。故为了了解yield,必然先要了解generator,而了解generator之前,我们先要了解一下迭代。 递归和迭...
    99+
    2023-01-31
    python yield
  • python setup.py bdist_wheel did not run successfully
    感谢阅读 问题描述解决方法一(治本)解决方法二(快但是不治本) 问题描述 安装webrtcvad时,报错python setup.py bdist_wheel did not run su...
    99+
    2023-09-03
    python 开发语言
  • python中Return浅析
       return 语句是Python语言中函数返回的一个值,每个函数都应该有一个返回值;其中,return返回值可以是一个数值,一个字符串,一个布尔值或者一个列表。    Python 函数返回值return ,函数中一定要有...
    99+
    2023-01-31
    python Return
  • python setup.py install 报错的解决
    可能是由于 Windows 的应用沙箱安全性限制导致的。在某些情况下,即使以管理员身份运行 PowerShell,也无法在受限的目录中创建或修改文件。 解决此问题的一种方法是选择一个不受限制的目录来安装 Python 包。你可以使用 --u...
    99+
    2023-09-22
    python 开发语言
  • Command "python setup.py egg_info" failed with error code 1
    我在使用pip3 install paramiko 的时候,出现了报错...         raise DistutilsError("S...
    99+
    2023-01-31
    setup py Command
  • Python中Setup.py的作用是什么
    今天就跟大家聊聊有关Python中Setup.py的作用是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。 1. 为什么需要对项目分发打包平常我们习惯了使用 pip 来安...
    99+
    2023-06-15
  • 已解决python setup.py bdist_wheel did not run successfully.
    已解决(pip安装第三方模块lxml模块报错)Building wheels for collected packages: lxml Building wheel for lxml (setup.p...
    99+
    2023-09-03
    python 开发语言 pip lxml模块安装
  • 浅析Python WSGI的使用
    目录什么是WSGIWSGI对应用程序规定了什么修改代码写出符合WSGI标准的web业务层总结第一次了解python的WSGI,可能描述的不太准确。 本篇文章所依赖的python环境为...
    99+
    2023-05-17
    Python WSGI使用 Python WSGI
  • 解决报错:python setup.py egg_info did not run successfully
    记录一下安装detectron2过程的解决debug经验,报错如下,主要是python setup.py egg_info did not run successfully: root@autodl-...
    99+
    2023-09-11
    python detectron2
  • 【Python】项目文件中如何安装 setup.py
    安装 setup.py 的过程与安装其他的 Python 包的过程类似。首先,你需要下载或者使用命令行中的 pip 安装 setuptools。你可以在 https://pypi.org/projec...
    99+
    2023-10-21
    python setup.py
  • Python函数的参数浅析
    这篇文章主要介绍“Python函数的参数浅析”,在日常操作中,相信很多人在Python函数的参数浅析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python函数的参数浅析”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-15
  • 浅析Python中的for 循环
    Python for 和其他语言一样,也可以用来循环遍历对象,本文章向大家介绍Python for 循环的使用方法和实例,需要的朋友可与参考一下。 一个循环是一个结构,导致第一个程序要重复一定次数。重复不断...
    99+
    2022-06-04
    Python
  • Python yield 使用方法浅析
    如何生成斐波那契盗/strong> 斐波那契(Fibonacci)盗惺且桓龇浅<虻サ牡莨槭校谝桓龊偷诙鍪猓我庖桓鍪伎捎汕傲礁鍪嗉拥玫健S眉扑慊绦蚴涑鲮巢瞧盗械那 N 个数是一个非常简单的问题,许多初学者都...
    99+
    2022-06-04
    使用方法 Python yield
  • 浅析Python实现DFA算法
    目录一、概述二、匹配关键词三、算法实现3.1、构建存储结构3.2、匹配关键词3.3、完整代码四、其他用法4.1、添加通配符一、概述 计算机操作系统中的进程状态与切换可以作为 DFA 算法的一种近似理解。如下图所示,其...
    99+
    2022-06-02
    Python DFA 算法 DFA
  • 浅析python中的set类型
    目录一. 定义二. 创建set1. 直接使用{}创建新的set并初始化2. 使用set关键字来创建3. 创建空的set三. 基本操作1. 重复的操作在set中自动被过滤2. 通过ad...
    99+
    2022-11-11
  • Python项目文件中安装 setup.py的步骤
    目录Python项目文件中安装 setup.py补充:python setup.py的作用Python项目文件中安装 setup.py 安装 setup.py 的过程与安装其他的 P...
    99+
    2023-05-19
    Python安装 setup.py Python setup.py
  • Python线程池的实现浅析
    目录一、序言二、正文1、Future 对象2、提交函数自动创建 Future 对象3、future.set_result 到底干了什么事情4、提交多个函数5、使用 map 来提交多个...
    99+
    2022-11-11
  • 浅析Python中的getattr(),setattr(),delattr(),hasattr()
    getattr()函数是Python自省的核心函数,具体使用大体如下: 获取对象引用getattr Getattr用于返回一个对象属性,或者方法 class A: def __init__(self...
    99+
    2022-06-04
    getattr Python setattr
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作