记录类
项目描述
记录
Records是一个Python库,它使得强大的结构类变得简单。
最简单的示例
Records的一个特性是,默认情况下,它所做的操作不比namedtuple或dataclass多。
from records import RecordBase
class Point(RecordBase):
x: float
y: float
z: float = 0.0
p0 = Point(x=0, y=0)
print(p0) # Point(x=0, y=0)
print(p0.x) # 0
# note that no type checking or coercion is performed
print(type(p0.y)) # int
# by default, the type hints are not even run
p1 = Point(x="hello", y="world", z="1.0")
print(p1.y) # world
print(type(p1.z)) # str
检查、强制转换和验证
有时我们希望在将参数输入结构之前执行一些额外的处理。为此,我们有三个步骤:类型检查、强制转换和验证
- 类型检查是第一步,也是最简单的一步,它只是检查参数是否是我们期望的类型。如果不是,那么我们将执行强制转换。
- 类型强制转换只有在类型检查失败的情况下才会发生,它将尝试将参数转换为期望的类型。正如人们所预期的那样,有许多潜在的强制转换器,因此它们必须单独添加。
- 验证在类型检查或类型强制转换成功后发生。到这时,我们已经确定输入是正确类型的,我们想要确保/操作其值。
这些方法通过字段描述,使用Annotation
类型提示(Annotation
是Python 3.9中引入的,但已被records
向后移植以用于旧版本)
这三个步骤在文档中有更详细的说明,现在我们将展示一些简短的示例
from typing import List
from records import RecordBase, Annotated, check, check_strict, Loose, Within, Eval
class Person(RecordBase):
first_name: str # no coercion or checking here, this is what we call a "hollow" field
last_name: Annotated[str, check] # now we will raise a TypeError if anyone tries to enter a non-string last_name
year_of_birth: Annotated[int, check_strict] # we will raise a TypeError if year_of_birth isn't exactly an int (so passing True will throw an error)
lucky_number: Annotated[int, check, Loose] # the "Loose" built-in coerser will simply call the destination type with the input as an argument, so that using `lucky_number="7"` would be equivalent to `lucky_number=int("7")`
number_of_children: Annotated[int, check, Within(ge=0)] # the Within built-in validator ensures the value is within stated bounds (in this case, at least zero)
# field tokens can even be more complex in case of nested field types
names_of_children: Annotated[List[Annotated[int, check, Eval]], check] # the list will be checked to be a list, and each item individually will be checked or coerced to be an int using the built-in Eval coercer.
# validators can also be added after declaration with pre_bind
@classmethod
def pre_bind(cls):
@cls.last_name.add_validator
def no_bad_words(last_name):
# we want to remove some words from the last name
return last_name.replace('richard', '*******')
# we can also add some more pre-processing on an entire instance with "post_new"
def post_new(self):
if len(self.names_of_children) != self.number_of_children:
raise ValueError("children mismatch")
解析
Records还可以从各种Python原语解析。包括从dict
、json和通用命名空间解析。
from types import SimpleNamespace
from records import RecordBase, check
class User(RecordBase, default_type_check=check):
name: str
password: str
age: int = 18
print(User.from_mapping({"name": "richard", "password": "swordfish"}))
print(User.from_json('{"name": "richard", "password": "swordfish"})'))
n = SimpleNamespace(user="rich", password="ard", age= 7)
print(User.from_instance(n))
# parsing can even be done if you expect misnamed fields!
from_upper_dict = User.from_mapping.select(keys_to_rename=[('user','name')], keys_to_remove=['favorite_color'])
print(from_upper_dict({'user':'richard', 'password': 'pw', 'favorite_color': 'red'}))
您还可以定义自己的解析器,甚至可以在构造中使用它们!
from math import sqrt
from records import RecordBase, check, SelectableFactory, parser
class Point(RecordBase, default_type_check=check):
x: float
y: float
z: float = 0
@parser
@SelectableConstructor
@classmethod
def from_tuple(cls, v):
return {'x':v[0], 'y':v[1], 'z':v[2] if len(v) > 2 else 0}
@property
def norm(self):
return sqrt(self.x**2 + self.y**2 + self.z**2)
p = Point([2,3,6])
print(p.norm) # 7
导出
Records还可以导出到各种格式(与解析相同)。
from records import RecordBase, check
class Point(RecordBase, default_type_check=check):
x: float
y: float
z: float
p = Point(x=2, y=3, z=6)
print(p.to_dict())
print(p.to_pickle())
# again, we can select to change the keys
print(
p.to_json.select(keys_to_add=[('w',0)])()
)
项目详情
下载文件
下载您平台对应的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。
源代码分发
recordclasses-0.0.1.tar.gz (30.4 kB 查看哈希值)
构建分发
recordclasses-0.0.1-py3-none-any.whl (35.6 kB 查看哈希值)
关闭
recordclasses-0.0.1.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2c4184679a4b823d0ea2a2157bcb8ce0da5f6dff61012b75114202d9b7c245a2 |
|
MD5 | d4afab5b269e950f9a19b2c22cb4aba8 |
|
BLAKE2b-256 | 802c2824237a68aa46ab558825b2af7a2816e64af10d0148208ca043e085ce25 |
关闭
recordclasses-0.0.1-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 8e7fbc4bc2eb0884b14dcddbfef2ba89ea6368a692af70642839a343be1bd4a3 |
|
MD5 | 7c387086470a894ac2cc9e03441abe1e |
|
BLAKE2b-256 | 99da81b354ff6d1694e491a952096cc0445b47ce46b048994bedb65a0c00ff67 |