一种框架,它支持用单元描述物理对象并易于序列化的类。

unitdoc的Python项目详细描述


unitdoc

unitdoc是一个python库,用于处理用单元描述物理对象并易于序列化的数据对象。让我们看一个例子。首先,导入unitdoc并创建将在应用程序中使用的注册表:

fromunitdocimportUnitDocRegistryudr=UnitDocRegistry()

让我们创建一个表示电池的类

importattr@udr.serialize()@attr.s()classBattery(object):name=attr.ib()weight=udr.attrib(default='45g')volume=udr.attrib(default='16ml',default_unit='ml')capacity=udr.attrib(default='3.0Ah')voltage=udr.attrib(default='3.6V',description='Average voltage')

我们可以创建一个Battery的实例,它将是一个普通的attr对象(参见attrs library),它具有一个很好的repr函数:

a_battery=Battery(name='battery',weight='43g')print(a_battery)# outputs: Battery(name='battery', weight=<Quantity(43, 'gram')>, volume=<Quantity(16, 'milliliter')>, capacity=<Quantity(3.0, 'Ah')>, voltage=<Quantity(3.6, 'volt')>)

我们可以在PINT软件包允许的任何操作中使用电池的属性:

energy=(a_battery.capacity*a_battery.voltage).to('Wh')energy_density=(energy/a_battery.weight).to('Wh/kg')print(f'{energy} @  {energy_density}')# outputs: 10.8 Wh @  251.2 Wh / kg

现在,让我们保存并重新加载电池对象:

# look at serialized formprint(a_battery.serialize())# outputs:name:batteryweight:!unit43gvolume:!unit16mlcapacity:!unit3Ahvoltage:!unit3.6V

这可以很容易地保存到文件中并重新加载:

fn='a_battery.yaml'# save to yaml filewithopen(fn,'w')asf:f.write(a_battery.serialize())# load from yaml filewithopen(fn,'r')asf:a_loaded_battery=Battery.deserialize(f.read())asserta_battery==a_loaded_battery

更多功能

unitdoc促进了某些操作,这些操作可以改进代码。

如果在属性中指定default_unit,数量将自动规范化为该单位:

a_battery=Battery(name='battery',volume='15903 mm^3')print(a_battery.volume)# outputs: 15.9 ml

如果指定了default_unit,任何不兼容的单元都将引发异常:

fromunitdocimportDimensionalityErrortry:a_battery=Battery(name='battery',volume='42 g')exceptDimensionalityErrorase:print(e)# outputs: Cannot convert from 'gram' ([mass]) to 'milliliter' ([length] ** 3)

您可以检索参数的说明,例如数据表示代码

fromunitdocimportget_attr_descriptionprint(get_attr_description(a_battery.__class__,'voltage'))# outputs: Average voltage

安装

使用包管理器pip安装unitdoc:

pip install unitdoc

或者,从git安装最新版本:

git clone https://github.com/deniz195/unitdoc
python unitdoc/setup.py install --user

相关套餐

unitdoc基于以下令人惊叹的软件包:

  • pint处理单位
  • ruamel.yamls处理半结构化数据(嵌套字典)的(反)序列化
  • attrs处理数据类的样板文件
  • cattr处理用于(反)序列化的类的非结构化和重组

unitdocregistry为每个包创建注册表/转换器/解析器并聚合它们。您可以利用每个软件包的功能:

从PINT使用单位注册表:

q=udr.ureg('1000gram').to('kg')print(q)# outputs: 1 kg

使用ruaml中的yaml解析器。yaml:

q_yaml=udr.yaml.dump(dict(weight=q))print(q_yaml)# outputs: weight: !unit 1 kg

使用cattr转换器:

@udr.serialize()@attr.s()classThing(object):weight=udr.attrib(default='45g',description='Total weight')a_thing=Thing()a_thing_dict=udr.cattr.unstructure(a_thing)asserttype(a_thing_dict)==dictprint(a_thing_dict['weight'])# output: 45 g

限制

考虑到attrs包的限制,安全地更新属性需要一定的预防措施。例如,给定上面的Battery类,以下是可能的,但不是理想的

a_battery=Battery(name='battery')a_battery.volume=99type(a_battery.volume)# outputs: int

这是不可取的,因为没有执行单元检查和规范化。

避免这种情况(和其他问题)的一个好方法是只使用关键字(kw_only=True)和冻结(frozen=Trueattr对象。

@udr.serialize()@attr.s(kw_only=True,frozen=True)classBetterBattery(object):name=attr.ib()weight=udr.attrib(default='45g')volume=udr.attrib(default='16ml',default_unit='ml')capacity=udr.attrib(default='3.0Ah')voltage=udr.attrib(default='3.6V',description='Average voltage')

仅限关键字的限制将不允许从位置参数创建对象,因此以下行将失败,并出现类型错误:

a_battery=BetterBattery('battery','42g','16ml')

这很好,因为当数据模型随时间变化时,位置参数可能很危险。下一行创建一个新对象,如果类发生更改,则该对象是稳定的

a_battery=BetterBattery(name='battery',weight='42g',volume='16ml')

冻结的实例限制不允许更改对象,因此此行将失败,并显示FrozenInstanceError

a_battery.volume=99

要更新值,可以使用attr.evolve函数,该函数使用更新的值创建新对象

a_battery=attr.evolve(a_battery,volume='12cm^3')

在这种情况下,按预期执行单位转换和检查。

虽然unitdoc与常规的attr类(@attr.s())一起工作,但我们强烈建议使用@attr.s(kw_only=True, frozen=True)

贡献

欢迎拉取请求。对于重大变更,请先打开一个问题来讨论您希望更改的内容。

请确保根据需要更新测试。

许可证

MIT

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java无法从spring resttemplate访问sms网关   使用spark上下文方法参数的java并行化集合不正确   java中ReadLock的并发检查副本   java基于属性比较两个列表是否具有相同的元素   字符串Java文本块:缩进前缀中的制表符和空格的混合   java如何将带有@SpringBootApplication的maven模块作为测试范围中的依赖项添加到另一个maven模块   我需要一些关于在Java中使用2个jar文件的帮助   mysql JPA Java Spring Boot执行查找/连接表   java对话框选择具有特定名称的文件   java如何修复Spring工具套件4中的端口8080错误?   Java中的apache poi Excel阅读器   java如何在tomcat访问日志中记录线程上下文值   java有一种方法可以创建类<T>的实例,该类将类作为传递泛型的构造函数中的参数   默认情况下,java GORM onetomany映射执行即时抓取   java不能在安卓中接受全局变量   统计系统的java MongoDB异步驱动程序排名   java如何解析:无法解析插件“org.springframework.ide.eclipse.ui”?   用Java从一副牌中随机抽取5张牌   javaapachecamel动态消费者   java如何克服使用Flood Fill 4算法时的“薄边界”问题?