Python笔记

人生苦短,写Python吧

数据科学

Matplotlib设置

在Spyder里提高默认的Inline figure分辨率,修改rcParams的默认文件是无效的,因为Spyder会自己设置,要在Spyder的Preference>IPython>Graphics里修改DPI。

MPL的默认配置文件

1
2
import matplotlib
matplotlib.matplotlib_fname()

可以得知该文件的位置,直接修改文件内容以配置matplotlib.rcParams字典的初始值。

显示中文字体,MPL的首选字体是不支持中文等Unicode的,所以需要把sans-serif(无衬线字体)的首选项改为一个支持中文的字体,比如微软雅黑。下载微软雅黑的TTF字体文件,放在MPL的字体路径上,通常是C:\Users\marti\Anaconda3\Lib\site-packages\matplotlib\mpl-data\fonts\ttf,然后修改

1
rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans', ...]

这样就可以在图标里显示中文的标题、坐标轴名称等文字了。

Package Manager: pip

我们在Gitlab CI 使用笔记中提到Gitlab可以在任何一个repo设置一个repo私有的PyPI。 那么,我们把使用git tag比如release/1.0.0这样的标签,推送到服务器触发CI,自动发布到PyPI上之后, 如何在任何一台有访问这个PyPI权限的电脑上安装package呢。

首先,PyPI是包含在Package Registry里面的,而Package Registry是Gitlab API的一部分,想要访问 PyPI,就必须先通过API的验证。Gitlab API的验证方式主要有三种

  • Private token,即你可以在Settings>Token里手动申请一个token,然后记住,来证明你的身份
  • CI job token,这个token在CI的容器环境内自动定义为一个环境变量,$CI_JOB_TOKEN
  • Deploy token,暂时不展开

一般创建一个单独的repo,用这个repo的Package Registry来存储全部项目的安装包

假设我们成功编译、测试、上传、发布了一个Python包到这个公共库的PyPI里面,打开PyPI的页面后,后看到

Installation Pip Command

1
pip install hello-world --extra-index-url https://__token__:<your_personal_token>@gitlab.example.com/api/v4/projects/:id/packages/pypi/simple

这个your_personal_token意味你必须要有权限才能从PyPI pip install hello-world

固然我们可以每次pip install都提供这串URL,但还是比较不方便,如何让pip在每次安装的时候不仅检索官方的index,也检索我们的私有PyPI呢?

pip提供了一个配置文件,这个文件在Windows里是用户目录文件下的%APPDATA%\pip\pip.ini, 如果没有这个文件就手动创建;在Unix是~/.config/pip/pip.conf,内容和格式是一样的。

1
2
3
4
5
6
7
[global]
proxy = http://127.0.0.1:8080
trusted-host = pypi.python.org
pypi.org
gitlab.example.com

extra_index_url = https://__token__:<your_personal_token>@gitlab.example.com/api/v4/projects/:id/packages/pypi/simple
  • pip install命令的很多参数,都可以在这个文件中配置,比如extra_index_url对应的就是pip install --extra-index-url
  • proxypip走代理
  • 如果你的PyPI server用的是私有证书,而且客户机没有信任该证书,trusted-host可以让pip不验证服务器的身份
  • 设置extra_index_url后所有的pip install都会额外检索这个PyPI

私有PyPI里的包建议和官方PyPI的包分开命名,比如package叫做hello-world,发布在PyPI的名称可以叫my-site-hello-world, 否则如果你的package和官方PyPI的package名字重合的话,你的pip install会优先安装官方的package

Debugger: pdb

pdb模块是python标准库中的Debugger。使用pdb debug程序可以

  • python -m pdb myscript.py,在脚本的第一行暂停进入调试状态
  • 在脚本中插入import pdb; pdb.set_trace(),运行脚本,可以调试该statement之后的代码;或者在Python 3.7+,built-in keyword breakpoint()起到同等效果

pdb也可以在Interactive Python中使用,支持post-mortem debugging,使得你可以在程序抛出错误后,使用pdb.pm() 恢复到异常抛出时的状态进行调试。

1
2
3
4
5
6
7
8
>>> import pdb
>>> def foo():
>>> print(bar)
>>> foo()
# NameError: name 'bar' is not defined ...
>>> pdb.pm()
-> print(bar)
(Pdb) # evaluate expression here

pdb显示(Pdb) prompt之后,可以输入任何Python表达式进行求值,也可以单步、进入函数或者运行到下一个断点。支持的命令如下

  • h 显示帮助
  • w (where) 打印堆栈信息
  • d (done) 在堆栈向下移动(向最近的函数调用方向移动)
  • u (up) 在堆栈向上移动(向最早的函数调用方向移动)
  • b (break) 接受一个lineon,设置一个断点在当前文件的该行,也可以接受一个函数名,停止在该函数的第一个statement
  • cl (clear) 清除所有断点
  • s (step) 运行当前行,如果是调用函数,Step into
  • n (next) 跟step类似,区别是next是几乎全速运行called function,停在当前函数的下一行,而不是called function中 举个例子
    1
    2
    3
    4
    5
    6
    7
    def foo():
    print('foo') # command 's' stops here

    def bar():
    breakpoint()
    foo() # pdb starts here
    print('bar') # command 'n' stops here
  • r (return) 继续运行直到当前函数返回
  • c (continue) 运行到下一个断点
  • l (list) 打印当前行附近的11行代码
  • ll (longlist) 当前当前函数的全部代码
  • a (args) 打印当前函数的参数
  • p (expression) 对表达式求值
  • pp (expression) 对表达式求值,用pprint打印
  • q (quit) 退出程序

Anaconda安装容易踩的坑

我的win11机器的HOME目录含有中文(计算机用户名为中文),在安装Anaconda python的时候,发现conda环境无论如何都无法在 Powershell 7中激活,conda init powershell也没有用。经过排查,发现运行conda init powershell后“用户”目录下面多了 一个乱码用户,这显然是Anaconda没有处理好中文字符,把Powershell的初始化文件写入了错误的路径。解决方法也很简单,把该 乱码目录下的全部文件拷贝到自己的HOME目录下,然后重启Terminal,可以看到(base)环境正常激活。

TA-Lib的Python绑定安装

在玩vnpy的时候,安装vnpy的图形界面客户端有一个依赖是TA-Lib,这个库因为是C++源码实现的,安装Python版本属于是Extension Module (含有C/C++依赖),众所周知处理起来很棘手,幸好网上有编译好的各平台的wheel,找到对应的platform + Python version 的wheel,pip install即可,不需要再去折腾MSVC的那一套编译工具。

某高校的Archive链接,比如你是x86_64,Python3.9,下载 TA_Lib‑0.4.24‑cp39‑cp39‑win_amd64.whl即可。

QtPy/PySide的启动问题

在启动最新版的vnpy的主窗口程序时,发现QT报错

1
"could not find or load the Qt platform plugin "windows" in "",

解决方法: 提供一些dll文件给QT的运行时环境,这些dll通常在PySide6的安装目录下都能找到。

设置环境变量 QT_QPA_PLATFORM_PLUGIN_PATH = ...\site-packages\PySide6\plugins\platforms

启动Qt窗口的时候可能会报一些warning,但不影响使用。