Python 包管理及虚拟环境的应用(二: virtualenv)

原本想在一篇之内覆盖到 Python 的包管理以及各类虚拟环境的应用,没想根本就是一发不可收拾,恐怕两篇都完不了,所以也要进行重构。这里只涉及到 Python 的虚拟环境 venv 和 virtualenv,至于标题的话,也不想再改了,只作一,二,三编号,必要时仍能连缀成长篇。最后一篇将单独学习 pipenv 的应用。

以下序号也是承接上一篇 Python 包管理及虚拟环境的应用(一)

2. Python 虚拟环境

关于创建 Python 项目的虚拟环境,有三个工具可用, venv, virtualenv, 以及后面单独要学到的 pipenv

  1. venv , 即 python3 -m venv 命令,Python 3.3 及新版本自带了,为 Python 3.4 及以后的版本创建的虚拟环境会有 pip 和 setuptools 命令
  2. virtualenv 需要单独安装,但是它支持 Python 2.7 和  Python 3.3+, 创建的虚拟环境中带有 pip, setuptools 和 wheel 命令
  3. 另外,pyvenv 脚本也可用来创建 Python 虚拟环境,不过它自 Python 3.6 不推荐使用,建议用 python3 -m venv 命令

阅读全文 >>

Python 包管理及虚拟环境的应用(一: pip)

话说 Python 的哲学之一就是: 用一种方法,最好是只有一种方法来做一件事。可以用 python -m this 或在  python 交互界面下 import this 看到 The Zen of Python 有一句:

There should be one-- and preferably only one --obvious way to do it.

然而 Python 在关于包管理(依赖管理)一事上却让人面临了众多的选择。

即使是 Java 日趋发展庞大的今天,包管理工具也没有如今的 Python 复杂,Java 的包管理工具经历了手工下载 jar 包,Maven, Ant+Ivy, Gradle, sbt, 但主流的也就 Maven 和 Gradle, 并且它们兼具项目构建的功能。

这里有一个 Python 包管理工具变迁的视频: Kenneth Reitz - Pipenv: The Future of Python Dependency Management - PyCon 2018。再更早的 Python 依赖管理的方式不说,视频中提到了 阅读全文 >>

Python 中的 urlencode 和 urldecode 操作

Web  编程中由于需要用 Form 或 URL 来传递参数,所以必然会有 urlencode 和 urldecode 的操作,Python Web 也不例外。Python 对 URL 的编解码操作提供了 urllib 模块,下面例子中所使用的 Python 版本是  3.6.7,不同的 Python 版本可能略有差异。

简面言之本文就是关于以下六个函数的使用,更多关于 urllib 的用法请自行进一步研究。

from urllib.parse import urlencode, parse_ql, quote, quote_plus, unquote, unquote_plus

为什么两个 urlencode 和  urldecode 操作会涉及到六个函数的应用呢,分别来讲述

1. urlencode

Python 的  urllib 直接提供了  urlencode 函数,它的操作数是一个字典 阅读全文 >>

让 Python 的数据库查询返回字典记录

在使用  Python 进行数据库查询,通常情况下 cursor 的 fetchall, fetchmany 返回的是元组(Tuple) 的列表,所以对查询到的结果只能用索引下标来访问,而无法通过字段名来获取值。对 Java JDBC 的 ResultSet 操作,我们有两种获取值的方式,resultSet.getString(1) 和 resultSet.getString('name')。

其实只要能用数字索引访问到字段值也就足够了,查询后字段名可以由 cursor.description 获得。通过字段名来访问值唯一的好处估计是出错的概率小些罢了,比如 result['firstname'], result['lastname'] 总是比 result[1], result[2] 更不容易搞混,错误定位也会更轻松。

假如有下面的数据库表与两条记录 阅读全文 >>

Python 版的 try-with-resources -- with 上下文管理器

作为一个  Java 为母语的程序员来讲,学习起其他新的语言就难免任何事都与 Java 进行横向对比。Java 7 引入了能省去许多重复代码的 try-with-resources 特性,不用每回 try/finally 来释放资源(不便之处有局部变量必须声明在  try 之前,finally 里还要嵌套 try/catch 来处理异常)。比如下面的  Java 代码

try(InputStream inputStream = new FileInputStream("abc.txt")) {
    System.out.println(inputStream.read());
} catch (Exception ex) {
}

它相应的不使用 try-with-resources 语法的代码就是 阅读全文 >>

用 .pth 文件附加 Python 模块搜索路径

上一篇 Python 的模块搜索路径,介绍了 Python 的模块搜索路径,最终起作用的是 sys.path 路径列表。如果要自定义自己的搜索路径,就是要怎么定制 sys.path 的内容。可以简单的用 PYTHONPATH 环境变量前向添加,这儿将要说的是用 .pth 文件的方式。也可由此进一步理解 Python 依赖管理工具,像  virtualenv 等的工作原理。

.pth 文件名是什么,无所谓,Python 只认扩展名。.pth 文件中每行指定一个路径 -- 绝对或相对路径(相对于本  .pth 文件所在的目录),另外还可以空行或 # 开始的注释行,还能有 import 语句,大概只用来校验是否能导入成功,程序代码中还是需要显示的 import 模块。

.pth 文件放在哪里

.pth 文件创建好后应该放到哪里去呢?不是 sys.prefix 指示的位置,也不是 sys.path 中任意一个目录,而是  sys.path 中属于 site.packages 的某一个目录中。可以用

>>> import site
>>> site.getusersitepackages()
>>> site.getsitepackages()

查看到, 看我在  Ubuntu Linux 中看到的内容(为便于阅读,显示列表内容时进行了换行处理) 阅读全文 >>

Python 的模块搜索路径

一种语言要使用到外部库(模块) 时必然会涉及到从哪里以及按何顺序加载依赖,就像 LD_LIBRARY_PATH, CLASSPATH 那样,Python 也有其默认的模块搜索顺序, 依序找到想要的模块即停止。Python 中 sys.path 返回的列表包含了模块搜索的顺序,我们可以程序中修改该列表,或用 PYTHONPATH 环境变量前插路径,甚至是用  .pth 文件来附加路径。

简单的,可以执行命令 python3 -c "import sys; print(str(sys.path).replace(',', '\n'))" 来查看 python3 交互 shell 下的模块搜索路径,类似结果如下:

[''
'/usr/lib/python36.zip'
'/usr/lib/python3.6'
'/usr/lib/python3.6/lib-dynload'
'/home/yanbin/.local/lib/python3.6/site-packages'
'/usr/local/lib/python3.6/dist-packages'
'/usr/lib/python3/dist-packages'
'/usr/lib/python3.6/dist-packages']

注意,第一个元素是个空字符串,代表进入 python3 shell 时的当前目录。

如果在通过一个 py 脚本文件来打印 sys.path 的话显示稍微有所差异。比如在目录 /home/yanbin/Developers/ 下创建 test.py 文件,内容为 阅读全文 >>

Python 的 __str__ 和 __repr__ 方法比较

阅读到 Strings 中关于转换对象为字符串的内容,介绍了 repr 函数,趁着还没有真正了解 Python 面向对象的生疏与热度,感性上理解一下 repr 与 str 这两个函数的区别。

Python 的全局方法 repr 和 str 会映射到对象的 __repr__ 和 __str__ 的方法调用,还有 str(obj) 时会调用哪个方法,以及 print(obj) 和调试 Python 代码时的对象显示会调用哪个方法呢?这就是本文想要印证的内容。

恰如 Java 的 System.out.println(obj) 或 "hello" + obj 都会调用 Java 对象的 toString() 方法,那么 Python 中是怎么一回事呢?

来自某本 Python 入门书的解释 repr 和 str:

  1. repr: formal string representation of a Python object
  2. str: informal string representation of a Python object,或者说 printable string representation

首先 repr 是 representation 的意思,一个是正式,另一个是非正式,看起来 repr 比 str 显得重要些。 阅读全文 >>

Apache 中运行 Python CGI 程序

Web 程序我还是喜欢用 Apache 来作为入口,因为我用的系统是 Mac OS, Apache 它就静静的躺上那儿了。最好是都像 PHP 那样的程序,无需启动额外的服务,这种使用方式的缺陷是不太适合于做微服务。

这儿呢,我也是来探索如何在 Apache 中运行 Python 的 CGI 程序,这主要是涉及了 Apache 与 Python 的集成。集成方式有直接集成(mod_python),CGI,FastCGI, WSGI 和 uWSGI。本文主要是讲如何运行一个简单的 Python CGI。

直接集成(mod_python)

虽然由于多方面的安全因素,这已经成为历史了,但还是提一下。参见

  1. Apache HTTP Server/mod_python(它推荐使用 mod_wsgi, 以下该节相关内容摘在本链接,没有亲自尝试)
  2. mod_python 官网(最后的更新是 2013-11-13)

需要安装模块 mod_python.so,并在 httpd.conf 加上相关的配置 阅读全文 >>

开始再战 Python - 重新入门 - 工具篇

两年前想摸摸 Python 的门道,简要记录了一篇 我的 Python 快速入门,当时只觉得那是一种与 C/Java 异样风格的编程语言,没领会到特别之处。如今对 Python 的感受就不一般了,因为是云服务,机器学习,人工知道大行其道的年代,所以更为急迫的想把它好好弄明白。

Python 3 说是设计的比  Python 2 要合理的多,所以没有保持向后兼容,现在初学 Python 对于选择哪个版本的 Python 时没有任何犹豫了,当然拣最新的 Python 3 学了。因此各种命令行工具都得用有 3 标记的,如  python3, pip3, pydoc3

编程语言特别是脚本语言,简单验证或入门最需要一个 REPL 工具,这里不论大型项目时最好选择全功能型的 IDE,像 PyCharm 这样的重型武器。在安装 Python 3 后,它自带了两个,分别是 python3 和 idle3(据说是 Integrated DeveLopment Environment 的缩写词, 可没见这么简陋的 IDE)

Python

命令 python3 进到控制台的 Python 交互界面,Python 标准的 >>> 提示符。没有语法高亮,没有自动缩进,唯一高级点的功能就是 tab 能对变量可以方法,属性的自动完成。 阅读全文 >>