添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在开始工作之前,自然需要先构建环境,但很多这方面资料都不够详尽。这对刚入门的初学者不是很友好。

还有一些时候,由于资料的年代过于老远,以至于所使用的环境已经不再适用。这导致不少人要耗费比较多的时间在环境构建上。

针对于此,本文大致整理了目前现阶段构建Python开发环境的方法以及牵涉到的工具。同时,也会大致介绍机器学习方面常用的软件包。

本文写于2020年初,将以当前主流的操作系统和软件版本为基础。

操作系统版本

对于开发者而言,不推荐大家使用Windows系统。本文使用开发者最常使用的macOS和Ubuntu系统为基础构建环境。对于其他Linux发行版的用户来说,本文应当也是适用的。

本文使用的系统版本如下:

  • macOS Catalina(10.15)
  • Ubuntu 18.04.3 LTS
  • Python 环境

    无论在macOS还是Ubuntu上,默认的 python 命令都是指的Python 2的版本。但这个版本将从 2020年开始逐渐退出历史舞台

    因此本文下面的内容只会涉及Python 3的内容。

    考虑到可能只有少部分人会这么做,因此本文不提及如何从源码安装Python。如果你真的想这么做,可以参考这篇文章: Installing Python 3.5.1 from source

    Python版本

    通常,Python 2的命令为 python ,而Python 3的命令为 python3 。大家可以通过下面这条命令查看Python 3的具体小版本号:

    $ python3 --version
      

    下文中,如果不加说明,所说的Python都是指Python 3。

    macOS上安装

    macOS Catalina上自带了Python 2,但是没有Python 3。

    不过如果你在命令行中输入python3,则会弹出下面这个对话框让你安装。

    点击“Install”并同意协议之后,便会自动开始安装。

    这种方法应该是最便捷的安装方式。但是除了这种方法,还有下面几种安装方法也很常用:

  • 和Xcode一起安装:如果你安装了Xcode,你会发现其中也包含了Python 3。其路径通常是这样:/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/。
  • 通过Python Installer安装。链接如下:Python Releases for Mac OS X
  • 通过Homebrew安装。
  • 相较而言,通过CommandLineTools方式安装最简单;通过Xcode安装则要占用较多的存储空间;通过Installer可以自主选择版本号(包括小版本号);通过Homebrew安装则卸载更新比较方便。

    如果你的系统上已经有了python3,但是不确定安装在哪里,你可以通过下文“环境确认”中提到的方法确认安装路径。

    Ubuntu上安装

    Ubuntu 18.04.3 LTS上正好相反:默认没有安装Python 2,不过安装了Python 3。但是其版本号比较低:

    $ python3 --version
    Python 3.6.8
    

    大家可以安装一个更新的版本。在Ubuntu上通常通过apt命令来管理软件包,可以通过下面这条命令安装3.7版本的Python。考虑到版本兼容性的问题,这个版本可能是现阶段最合适的。

    $ sudo apt install python3.7
      

    通过apt list命令可以查看所有安装的软件包

    在安装完成之后,系统中将有两个版本的Python(3.6和3.7)共存。但是系统默认并不会使用新安装的版本。不过我们可以改变默认的版本。

    我们可以使用update-alternatives命令将新版本的可执行文件设置较高的优先级即可。该命令格式如下:

    $ update-alternatives --install <link> <name> <path> <priority>
    

    于是我们执行

    $ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1
    $ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2
    

    再次查看版本时,会发现python3已经指向新的版本:

    $ python3 --version
    Python 3.7.3
    

    在这之后,如果还想要切换Python版本,可以通过下面这条命令选择默认版本:

    $ sudo update-alternatives --config python3
    There are 2 choices for the alternative python3 (providing /usr/bin/python3).
      Selection    Path                Priority   Status
    ------------------------------------------------------------
    * 0            /usr/bin/python3.7   2         auto mode
      1            /usr/bin/python3.6   1         manual mode
      2            /usr/bin/python3.7   2         manual mode
    Press <enter> to keep the current choice[*], or type selection number: 
    

    这个时候可以通过输入具体的数字来选择需要的版本。

    可以通过which命令查看python3命令的可执行文件路径。例如:

    $ which python3                                                      
    /usr/bin/python3
    

    很多时候,这里返回的路径可能只是一个链接,因此还需要通过ls -l命令来确认:

    $ ls -l /usr/bin/python3
    lrwxrwxrwx 1 root root 25 11月  4 23:00 /usr/bin/python3 -> /etc/alternatives/python3
    

    从这个输出可以看出,实际的python3可执行文件其实是/etc/alternatives/python3

    绝大部分Python程序都不会是由一个文件构成,通常会包含了定义在多个文件中的内容。

    你可以简单的认为,一个.py的Python文件就是一个模块。

    严格的讲,Python中的模块有两种形式:

  • 纯模块(Pure Module):这就是通过Python语言编写的单个.py文件。
  • 扩展模块(Extension Module):通过底层语言(例如:C/C++)编写并且预编译的文件(例如Linux/Unix上的.so)。
  • 模块是程序的组成单元,它将代码和数据封装起来以便复用。同时,模块提供了自包含的命名空间从而避免程序出现变量名冲突。

    以下面这个两行的代码为示例,这里导入一个名称为platform的模块。同时,也将这个模块命名为同名的变量。接下来我们就可以使用platform这个变量了。

    import platform
    print(platform.platform())
    

    一个import语句中的模块名起到了两个作用:

  • 识别外部加载的文件
  • 赋值被载入模块的变量
  • 通常,在程序中我们使用的模块有三个来源:

  • Python语言标准库中定义的模块。 这通常在安装Python的时候就一起包含了。可以到这里查看这些模块的说明:The Python Standard Library
  • 第三方开发者提供的模块。 这通常是一些开源软件,例如:numpypandas等。
  • 通过源码形式使用的模块。 这通常是我们自己项目中开发的模块。
  • import 如何工作

    与C/C++语言中的#include不一样。在Python中,import并非只是把一个文件文本插入另一个文件。导入其实是运行时的操作。

    程序第一次导入执行文件时,会执行三个步骤:

  • 搜索:这一步是找到所引用模块的物理文件。具体见下面的“模块搜索路径”。
  • 编译(可选)::如果需要,Python接下来会将模块编译成字节码。
  • 运行import操作最后的步骤是执行模块的字节码。文件中所有的语句都会被执行。并且,此时任何对名称的赋值运算,都会产生所得到的模块对象的属性。
  • 模块搜索路径

    当我们使用标准库以外的模块时,我们很可能要关心import是如何搜索文件的。如果不然,我们很可能会遇到下面这个错误:

    ModuleNotFoundError: No module named 'xxxx'
    

    总的来说,Python会根据以下5个信息搜索模块:

    Python始终会从左至右搜索这个列表以加载模块。因此优先级更高的路径将覆盖低优先级目录中的同名模块。

    从上面的表格中我们也看到,Python提供了PYTHONPATH环境变量和.pth文件两种方式让我们配置搜索路径。

    因此,通过export PATHONPATH=xxx的方式就可以将目录添加到搜索路径中。

    .pth文件的方式相对不那么常用。不过当存在.pth文件时,Python会把文件每行所罗列的目录从头至尾地添加到模块搜索路径列表中。

    在Python世界里,“包”有两个含义:

  • 模块包(Module Package):或者叫做导入包(Import Package),这是大家通常简称的“包”。这是一个Python模块,可以递归的包含其他包或者模块。
  • 分发包(Distribution Package):这是版本化的存档文件,其中包含用于分发发行版的Python软件包,模块和其他资源文件。最终用户将从互联网下载并安装该该存档文件。
  • 这其中,模块包对应了开发编码时的概念。分发包对应了构建项目环境时的概念。

    这里我们先介绍模块包,下文会继续介绍分发包。

    对于import来说,除了可以导入模块名之外,还可以指定目录路径。Python代码的目录被称为包,因此这样的导入就称为包导入。

    模块包提供了组织多层次大型项目的功能。

    如果选择使用包导入,就必须遵循一条约束。那就是:包导入语句的路径中每个目录内都必须有一个__init__.py文件(即便这个文件的内容可能是空的)。

    例如,当我们使用import dir1.dir2.mod时。dir1dir2目录中都必须包含一个__init__.py文件。__init__.py文件承当了包初始化的职责。

    当然,dir1所属的父目录还要在sys.path列表列表中。

    在开发Python程序时,单单标准库常常并不能完全满足我们的需求。我们还需要依赖其他第三方项目。这些项目以分发包的形式发布产物供我们使用。

    这就要提一下PyPA和PyPI了。

    PyPA(Python Packaging Authority)是一个工作组,负责维护Python打包中使用的一系列核心项目。

    PyPA开发的软件用于打包,共享和安装Python软件,并与可下载的Python软件索引(例如PyPI)进行交互。

    PyPA发布了《Python Packaging User Guide》作为有关如何使用当前工具打包,发布和安装Python项目的权威资源。

    PyPI(Python Package Index)是Python社区的默认包索引。它对所有Python开发人员开放,使得他们可以使用它来获取和发布分发包。

    常用机器学习包

    在机器学习中,下面是一些大家常用的包。关于它们的更多信息可以访问官网获取。

  • jyputer
  • 官网:https://jupyter.org
  • 介绍:Jupyter Notebook(前身是IPython Notebook)是一个基于Web的交互式计算环境,用于创建Jupyter Notebook文档。借助这个工具,我们可以直接在浏览器里面编写和运行Python程序。
  • keras
  • 官网:https://keras.io
  • 介绍: Keras是一个用Python编写的开源神经网络库,能够在TensorFlow、Microsoft Cognitive Toolkit、Theano或PlaidML之上运行。Keras旨在快速实现深度神经网络,专注于用户友好、模块化和可扩展性。
  • matplotlib
  • 官网:https://matplotlib.org
  • 介绍:matplotlib是Python编程语言及其数值数学扩展包 NumPy的可视化操作界面。它利用通用的图形用户界面工具包,如Tkinter, wxPython, Qt或GTK+,向应用程序嵌入式绘图提供了应用程序接口。
  • numpy
  • 官网:https://numpy.org
  • 介绍:NumPy是Python语言的一个扩展程序库。支持高端大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
  • opencv
  • 官网:http://opencv.org
  • 介绍:OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序。
  • pandas
  • 官网:https://pandas.pydata.org
  • 介绍:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
  • Pillow
  • 官网:https://pillow.readthedocs.io/en/stable/
  • 介绍:Python Imaging Library,Python平台事实上的图像处理标准库。
  • protobuf
  • 官网:https://developers.google.com/protocol-buffers/
  • 介绍:Google开源的工具。一种数据交换的格式,它独立于语言,独立于平台。Google 提供了多种语言的实现:Java、C#、C++、Go 和 Python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用XML进行数据交换快许多。
  • scikit-image
  • 官网:https://scikit-image.org
  • 介绍:SciKit Image 是一个专门用于图像处理的 Python 包。
  • scipy
  • 官网:https://www.scipy.org
  • 介绍:SciPy是一个开源的Python算法库和数学工具包。SciPy包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。
  • tensorflow
  • 官网:https://www.tensorflow.org
  • 介绍:TensorFlow是一个开源软件库,最初由谷歌大脑团队开发,用于Google的研究和生产。它被用于各种感知和语言理解任务的机器学习。
  • turicreate
  • 官网:https://github.com/apple/turicreate
  • 介绍:苹果开源的机器学习工具。
  • 分发包打包主要使用setuptoolswheel两个工具。

    分发包使用称之为Wheel的格式发布。该格式由PEP 427 – The Wheel Binary Package Format 1.0定义。

    打包和发布通常只有分发包的开发者才需要这方面知识,所以这里我们不讨论。接下来我们介绍分发包的安装和虚拟环境的管理。

    对于Python来说,使用pip来安装和卸载分发包。

    Python 3对应的pip命令为pip3

    在macOS上,无论是通过上面提到的四种方法中的哪一种安装了Python(或者是通过源码安装),pip都会一并安装好。

    查看pip版本时就能看到其所属的环境。例如,下面是通过CommandLineTools方式安装的Python。

    $ pip3 --version
    pip 19.0.3 from /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/site-packages/pip (python 3.7)
    

    下面是通过Xcode方式安装了Python。

    pip3 --version
    pip 19.0.3 from /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/site-packages/pip (python 3.7)
    

    但是在Linux上就没这么方便了。你需要手动安装pip。

    在Ubuntu系统上,通过下面这条命令安装pip3:

    $ sudo apt install python3-pip
      

    其他发行版的Linux安装pip的方法见这里:Installing pip/setuptools/wheel with Linux Package Managers

    pip默认从Python Package Index上下载包。使用pip可以查询,安装和卸载包。下面是一些使用示例:

  • pip3 search查询包信息:
  • $ pip3 search turicreate
    turicreate (5.8)  - Turi Create simplifies the development of custom machine learning models.
      INSTALLED: 5.8 (latest)
      
  • pip3 install安装某个包的最新版本:
  • $ pip3 install novas
    Collecting novas
      Downloading novas-3.1.1.3.tar.gz (136kB)
    Installing collected packages: novas
      Running setup.py install for novas
    Successfully installed novas-3.1.1.3
      
  • 通过==安装某个包的特定版本:
  • $ pip3 install requests==2.6.0
    Collecting requests==2.6.0
      Using cached requests-2.6.0-py2.py3-none-any.whl
    Installing collected packages: requests
    Successfully installed requests-2.6.0
      
  • pip3 install --upgrade更新包
  • $ pip3 install --upgrade requests
    Collecting requests
    Installing collected packages: requests
      Found existing installation: requests 2.6.0
        Uninstalling requests-2.6.0:
          Successfully uninstalled requests-2.6.0
    Successfully installed requests-2.7.0
      
  • pip3 show查询包信息:
  • $ pip3 show scipy
    Name: scipy
    Version: 1.3.1
    Summary: SciPy: Scientific Library for Python
    Home-page: https://www.scipy.org
    Author: None
    Author-email: None
    License: BSD
    Location: /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages
    Requires: numpy
    Required-by: turicreate, scikit-learn, scikit-image, resampy, ImageHash
      
  • pip3 list列出所有已经安装的包:
  • $ pip3 list 
    Package               Version  
    --------------------- ---------
    absl-py               0.8.1    
    astor                 0.8.0    
    awscli                1.16.271 
    boto3                 1.10.7   
    botocore              1.13.7   
    certifi               2019.9.11
    chardet               3.0.4    
    Click                 7.0      
    colorama              0.4.1    
    coremltools           3.0b3    
    cycler                0.10.0
    

    python -m pip

    如果你的系统上同时有多个Python存在。那么直接运行pip命令可能并不是一个好的选择。因为这个时候很难确定使用的是哪一个环境中的。

    在这种情况下,通过指定python可执行文件的全路径来运行pip会比较好。例如:

    /Library/Frameworks/Python.framework/Versions/3.7/bin/python3 -m pip list
    

    之所以可以这么做,是因为pip是Python一个模块。Python可执行文件提供了这样一个参数:

    -m mod : run library module as a script (terminates option list)
    

    关于这个参数的详细说明,请看这里:-m <module-name>

    尽管不是必须的,但在一些时候,我们可能同时需要多个Python环境并存。

    例如:某些项目需要专门的Python版本,或特定包的特定版本。又或者,某些包只在某个项目中使用,不希望它出现在全局的环境中。这个时候就可以通过虚拟环境来管理。

    虚拟环境使得我们可以创建一个或多个隔离的环境,环境中包含了Python以及一系列的包,我们可以方便的在不同的环境之间切换,并且互不干扰。虚拟环境可以自由的创建和删除(这和我们电脑上使用的虚拟机是非常类似的)。

    围绕这个方面的工具非常多,包括下面这些:

  • virtualenv
  • pyenv
  • pyenv-virtualenv
  • virtualenvwrapper
  • pyenv-virtualenvwrapper
  • pipenv
  • pyvenv
  • 我们当然不会每个都介绍,关于它们的区分可以看下面的两个链接:

  • What is the difference between venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, pipenv, etc?
  • 接下来仅仅介绍大家最为常用的两个。

    从Python 3.3开始,venv已经是Python标准的一部分。

    但是即便如此,在Ubutnu上还是需要手动安装venv。并且安装时的版本号要与Python版本号一致。例如,安装Python时指定了3.7版本。则安装venv也要指定同样的版本:

    sudo apt install python3.7-venv
    

    venv模块提供了创建轻量级虚拟环境的功能。虚拟环境位于专门的目录中,可以与系统主目录相隔离。每个虚拟环境都有自己的Python二进制文件(与用于创建该环境的二进制文件的版本匹配),并且虚拟环境可以在其站点目录中拥有自己独立安装的Python软件包集。

    创建虚拟环境的命令非常简单:

    python3 -m venv <VENV_DIR>
    

    这里的<VENV_DIR>是你可以任意指定的目录。如果该目录不存在,则会自动创建。

    这条命令执行完成之后,<VENV_DIR>中会出现关于虚拟环境的一系列文件。你可以通过tree命令查看其目录结构:

    $ tree venv_dir
    venv_dir
    ├── bin
    │   ├── activate
    │   ├── activate.csh
    │   ├── activate.fish
    │   ├── easy_install
    │   ├── easy_install-3.7
    │   ├── pip
    │   ├── pip3
    │   ├── pip3.7
    │   ├── python -> python3
    │   └── python3 -> /Library/Frameworks/Python.framework/Versions/3.7/bin/python3
    ├── include
    ├── lib
    │   └── python3.7
    │       └── site-packages
    │           ├── __pycache__
    │           │   └── easy_install.cpython-37.pyc
    │           ├── easy_install.py
    │           ├── pip
    │           │   ├── __init__.py
    │           │   ├── __main__.py
      

    Mac上默认没有tree命令。如果你安装了Homebrew,你可以通过它来安装:brew install tree

    刚创建的虚拟环境是没有生效的,你还需要通过下面这条命令将其生效:

    source <VENV_DIR>/bin/activate
    

    执行完成之后,命令提示符会包含虚拟环境名称的前缀。同时,你也可以通过which命令查看新的Python可执行文件路径:

    (venv_dir) $ which python3
    /Users/paul/Downloads/venv_dir/bin/python3
    

    在这之后,你再通过pip3来安装包将安装在虚拟环境所在的目录中。

    如果你想退出虚拟环境回到系统主环境,输入deactivate即可。

    virtualenv

    virtualenv是一个第三方包,所以通过pip安装即可:

    pip3 install virtualenv
    

    如果出现Permission denied,则需要带上--user参数,只为当前用户安装:

    pip3 install --user virtualenv
    

    venv和virtualenv有稍许不一样的地方,对比如下:

    事实上,venv的实现很大程度上是基于virtualenv的,因此两者非常相似。virtualenv虚拟环境的生效和退出与venv是完全一样的。

    如果你通过diff工具(例如:diffmerge)对比两者生成的文件夹,你会发现文件列表都是几乎一样的。

    Conda

    有不少的Python开发者会使用Conda。

    这是一个开源的包管理系统,它支持Windows,macOS和Linux。它支持的语言远不只是Python,还有R, Ruby, Lua, Scala, Java, JavaScript, C/C++, FORTRAN。

    Conda作为软件包管理器可以查找和安装软件包。如果需要一个使用不同版本的Python的软件包,则无需切换到其他环境管理器,因为conda也是环境管理器。仅需几个命令,就可以设置一个完全独立的环境来运行该不同版本的Python,同时继续在正常环境中运行通常的Python版本。

    Conda有三个产品可供选择:

  • Anaconda:免费,适合新手。自带了超过150个科学计算包。占用空间较大。
  • Miniconda:免费,占用空间小,可以方便的自行安装软件包。
  • Anaconda Enterprise:收费的商业版本产品。
  • 另外,安装包会有带界面的版本和命令行版本。使用Conda,你不用再自己安装Python,Anaconda和Miniconda自带了Python 2.7,Anaconda3和Miniconda3自带了Python 3.7。

    以下以Miniconda为例,介绍如何使用。

    对于Miniconda来说,提供了macOS和Ubuntu的.sh安装脚本。下载安装脚本之后赋予可执行权限,然后运行该脚本即可完成安装:

    $ chmod a+x Miniconda3-latest-MacOSX-x86_64.sh
    $ ./Miniconda3-latest-MacOSX-x86_64.sh
    

    默认的安装目录是用户Home目录下,会新建一个miniconda3目录。在安装之后选择激活,然后重启命令行就可以使用了。可以通过下面的命令确认:

    $ which python3
    /home/paul/miniconda3/bin/python3
    

    conda的激活方式其实就是在shell启动脚本中插入了一些conda的初始化脚本。例如,在Ubuntu上查看~/.bahrc可以看到这部分内容:

    # >>> conda initialize >>>
    # !! Contents within this block are managed by 'conda init' !!
    __conda_setup="$('/home/paul/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
    if [ $? -eq 0 ]; then
        eval "$__conda_setup"
        if [ -f "/home/paul/miniconda3/etc/profile.d/conda.sh" ]; then
            . "/home/paul/miniconda3/etc/profile.d/conda.sh"
            export PATH="/home/paul/miniconda3/bin:$PATH"
    unset __conda_setup
    # <<< conda initialize <<<
    

    激活Conda之后,你就有了conda命令。使用该命令可以轻松的管理软件包。当然,Conda也支持类似虚拟环境的功能。其帮助说明如下:

    $ conda --help
    usage: conda [-h] [-V] command ...
    conda is a tool for managing and deploying applications, environments and packages.
    Options:
    positional arguments:
      command
        clean        Remove unused packages and caches.
        config       Modify configuration values in .condarc. This is modeled
                     after the git config command. Writes to the user .condarc
                     file (/home/paul/.condarc) by default.
        create       Create a new conda environment from a list of specified
                     packages.
        help         Displays a list of available conda commands and their help
                     strings.
        info         Display information about current conda install.
        init         Initialize conda for shell interaction. [Experimental]
        install      Installs a list of packages into a specified conda
                     environment.
        list         List linked packages in a conda environment.
        package      Low-level conda package utility. (EXPERIMENTAL)
        remove       Remove a list of packages from a specified conda environment.
        uninstall    Alias for conda remove.
        run          Run an executable in a conda environment. [Experimental]
        search       Search for packages and display associated information. The
                     input is a MatchSpec, a query language for conda packages.
                     See examples below.
        update       Updates conda packages to the latest compatible version.
        upgrade      Alias for conda update.
    optional arguments:
      -h, --help     Show this help message and exit.
      -V, --version  Show the conda version number and exit.
    

    conda要比pip更加强大,以下是两者的对比:

  • Virtual Environments and Packages
  • PEP 405 – Python Virtual Environments
  • PEP 427 – The Wheel Binary Package Format 1.0
  • Learning Python 5th Edition
  • What is the difference between venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, pipenv, etc?
  • venv — Creation of virtual environments
  • Virtualenv
  • Why you should use python -m pip
  • Python Virtual Environments: A Primer
  • Python Virtual Environments made easy
  •