向后兼容性
GPIO Zero 2.x 是一个新的主要版本,因此向后不兼容的更改是可以预期的。我们试图将这些变化保持在合理的最小范围内,同时利用这个机会来进行清理。本章记录了从 GPIO Zero 1.x 版本到 2.x 版本的重大变化,以及所有在 2.0 版本中仍可正常工作但计划在未来 2.x 版本中删除的过时功能。
查找并修复被弃用的用法
从 2.0 版开始,所有被弃用的功能在使用时都会引发 DeprecationWarning
。默认情况下,Python 解释器会抑制这些警告(因为它们只对开发者有意义,而不是用户),但您可以很容易地配置不同的行为。
下面的示例脚本使用了一些已废弃的函数:
import gpiozero
board = gpiozero.pi_info()
for header in board.headers.values():
for pin in header.pins.values():
if pin.pull_up:
print(pin.function, 'is pulled up')
尽管使用了过时的功能,脚本仍能在 gpiozero 2.0 中正常(无声)运行。为了发现使用了哪些已废弃的函数,我们添加了几行文字,告诉警告模块我们希望 "默认" 处理 DeprecationWarning
;"默认" 处理意味着,第一次尝试在特定位置引发警告时,警告的详细信息将被打印到控制台。以后从同一位置发出的所有调用都将被忽略。这样可以避免在控制台中充斥来自紧密循环的警告细节。这样,脚本看起来就像这样了:
import gpiozero
import warnings
warnings.filterwarnings('default', category=DeprecationWarning)
board = gpiozero.pi_info()
for header in board.headers.values():
for pin in header.pins.values():
if pin.pull_up:
print(pin.function, 'is pulled up')
运行时,控制台会产生以下输出:
/home/dave/projects/home/gpiozero/gpio-zero/gpiozero/pins/__init__.py:899:
DeprecationWarning: PinInfo.pull_up is deprecated; please use PinInfo.pull
warnings.warn(
/home/dave/projects/home/gpiozero/gpio-zero/gpiozero/pins/__init__.py:889:
DeprecationWarning: PinInfo.function is deprecated; please use PinInfo.name
warnings.warn(
GPIO2 is pulled up
GPIO3 is pulled up
这告诉我们脚本中使用了哪些已废弃的功能,但并没有告诉我们在脚本的哪个位置使用了这些功能。为此,将警告转换为完整的异常更为有用。有了这一改动,每次打印 DeprecationWarning
时,脚本都会以未处理异常和完整的堆栈跟踪结束:
import gpiozero
import warnings
warnings.filterwarnings('error', category=DeprecationWarning)
board = gpiozero.pi_info()
for header in board.headers.values():
for pin in header.pins.values():
if pin.pull_up:
print(pin.function, 'is pulled up')
现在运行脚本,结果如下:
Traceback (most recent call last):
File "/home/dave/projects/home/gpiozero/gpio-zero/foo.py", line 9, in <module>
if pin.pull_up:
File "/home/dave/projects/home/gpiozero/gpio-zero/gpiozero/pins/__init__.py", line 899, in pull_up
warnings.warn(
DeprecationWarning: PinInfo.pull_up is deprecated; please use PinInfo.pull
这告诉我们脚本的第 9 行使用了已废弃的功能,并提示我们如何修复。我们将第 9 行改为使用 "pull" 属性。现在我们再次运行,这次得到的结果如下:
Traceback (most recent call last):
File "/home/dave/projects/home/gpiozero/gpio-zero/foo.py", line 10, in <module>
print(pin.function, 'is pulled up')
File "/home/dave/projects/home/gpiozero/gpio-zero/gpiozero/pins/__init__.py", line 889, in function
warnings.warn(
DeprecationWarning: PinInfo.function is deprecated; please use PinInfo.name
现在我们可以看出第 10 行有问题,异常再次告诉我们如何修复。我们继续这样做,直到脚本看起来像这样:
import gpiozero
import warnings
warnings.filterwarnings('error', category=DeprecationWarning)
board = gpiozero.pi_info()
for header in board.headers.values():
for pin in header.pins.values():
if pin.pull == 'up':
print(pin.name, 'is pulled up')
现在脚本运行完成,因此我们可以确信它不再使用任何过时的功能,即使在未来的 2.x 版本中删除了这些功能,它也能正常运行。此时,你也可以删除 filterwarnings
一行(或至少将其注释掉)。
不再支持 Python 2.x
到目前为止,最大、最重要的变化是不再支持 Python 2.x 系列(实际上,这意味着不再支持 Python 2.7)。如果您的代码与 Python 3 不兼容,则应遵循 Python 文档 中的 移植指南。
GPIO Zero 2.0 支持的最低 Python 版本为 3.5。这个基础版本可能会随着小版本的发布而提高,但我们会尽最大努力不破坏与旧 Python 3.x 版本的兼容性,并确保 GPIO Zero 能在发布时 Debian oldstable 中的 Python 版本上运行。
删除 RPIO 引脚工厂
RPIO 引脚在 Raspberry Pi 2 以后的版本中已不支持,因此目前几乎没有实际用途。建议仍然依赖 RPIO 稳定 PWM 实现的用户尝试使用 pigpio 引脚实现(GPIO Zero 也支持)。