跳转到主要内容

Jupyter和IPython的物理单位字面量

项目描述

unit-syntax 向Python语言添加了对物理单位的支持

>>> speed = 5 meters/second
>>> (2 seconds) * speed
10 meter

为什么?我喜欢将Python用作物理问题的计算器,希望它具有显式单位的安全性和普通记法的可读性。

unit-syntax 适用于Jupyter笔记本、独立的Python脚本和Python包。

它是如何工作的?

入门

安装包

$ pip install unit-syntax

... 在Jupyter/IPython中

要在Jupyter/IPython会话中启用unit-syntax,请运行

%load_ext unit_syntax

提示:在Jupyter中,必须在评估任何单位表达式之前,在单独的单元中运行此命令。

... 在独立的脚本中

要运行带有单位的独立脚本

$ python -m unit_syntax <path_to_script.py>

注意,这会安装一个自定义导入钩子,该钩子会影响脚本执行的任何导入。

... 在Python包中

要使用/分发带有unit-syntax的包,请将此添加到您的 __init__.py

from unit_syntax.import_hook import enable_units_for_package
enable_units_for_package(__name__)

这仅适用于您的包的子模块。

使用方法

一个用于探索单位的交互式笔记本

单位可以应用于任何“简单”表达式

  • 数字: 1米
  • 变量: x parsecy.z 瓦特area[id] 米**2
  • 列表和元组: [1., 37.] 牛顿米
  • 一元运算符: -x dBm
  • 幂: x**2 米

在混合单位与二进制运算符的表达式中,需要使用括号

one_lux = (1 lumen)/(1 meter**2)

单位可以在Python允许表达式的任何地方使用,例如

  • 函数参数: area_of_circle(radius=1 米)
  • 列表推导式: [x 米 for x in range(10)]

量可以转换为另一个度量系统

>>> (88 miles / hour) furlongs / fortnight
236543.5269120001 furlong / fortnight
>>> (0 degC) degF
31.999999999999936 degree_Fahrenheit

复合单位(例如 newtons/meter**2)受支持,并遵循常规优先级规则。

单位可能不能以括号开头(考虑x (meters)的可能解释)。括号可以在其他任何地方使用。

# parsed as a function call, will result in a runtime error
x (newton meters)/(second*kg)
# a-ok
x newton meters/(second*kg)

使用未知单位会在导入时产生语法错误。

>>> 1 smoot
...
SyntaxError: 'smoot' is not defined in the unit registry

它是如何工作的?

unit-syntax将带有单位的Python代码转换为标准的Python代码,该代码调用优秀的pint单位处理库。

解析器是pegen,它是Python自身所使用的相同解析器生成器的独立版本。语法是一个略微修改后的版本,即随pegen一起发布的官方Python语法。

IPython/Jupyter中的语法转换使用IPython自定义输入转换器

任意Python模块的语法转换使用importlibMetaPathFinder,请参阅import-transformsunit_syntax.import_hook以获取详细信息。

为什么只允许在简单表达式中使用单位?

想象一下,如果单位被解析为具有高优先级的运算符,而你写了这样一个看起来合理的表达式

ppi = 300 pixels/inch
y = x inches * ppi

inches * ppi将被解析为单位,导致(最好)稍后运行时错误,最坏的情况是不正确的计算。这可以通过括号化表达式来避免(例如,(x inches) * ppi,但如果这是可选的,很容易忘记。因此,此限制的目的是使这些风险形式不常见,从而使它们更加明显。这不仅仅是一个假设的担忧,我在使用初始语法的10分钟内就遇到了这个问题。

现有技术

unit-syntax的直接灵感来自Sun Microsystems的一个名为Fortress的语言。Fortress被设计为现代的Fortran,在语法和类型系统中都提供了对单位的一等支持。

Microsoft的F#(一种OCaml衍生物)也有一等支持单位

Julia包Unitful.jl

关于Python中字面单位的长篇讨论

开发

要重新生成解析器

python -m pegen python_units.gram -o unit_syntax/parser.py

运行测试

$ poetry install --with dev
$ poetry run pytest

未来的工作和开放性问题

  • 针对不同的ipython和python版本进行测试
  • 确保字节码缓存仍然工作
  • 使用通配符加载器测试更广泛的源文件
  • 单位类型提示,可能使用@runtime_checkable进行检查。更多Pint类型检查讨论
  • 输出排版
  • 预解析单位
  • 与pint讨论UnitRegistries之间的互操作性
  • 修复缺少括号时报告的SyntaxError的位置

项目详情


下载文件

下载适合您平台的项目文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

unit_syntax-0.3.1.tar.gz (36.6 kB 查看哈希值)

上传时间 源码

构建发行版

unit_syntax-0.3.1-py3-none-any.whl (35.8 kB 查看哈希值)

上传时间 Python 3

支持者