我有一个非常灵活的
dataclass
使用策略,但我不确定它是否依赖于不属于类型契约的功能。我经常告诉人们不要依赖 python 中 dict
的可迭代顺序插入顺序,因为只有 OrderedDict
具有该属性作为契约,并且不同版本的 python 可能会有不同的行为。
这样的图案有什么顾虑吗?它给了我很大的灵活性来利用
dataclass
的功能,这些功能具有这样的属性分离。
from abc import ABC
from dataclasses import dataclass, fields
class BQTransformer(ABC):
_project: str = 'default-project-name'
_dataset_wo_version: str
_dataset_version: str
_default_table: str
@classmethod
def get_dataset(cls):
return f'{cls._dataset_wo_version}_v{cls._dataset_version}'
@classmethod
def table(cls, table_name=None) -> str:
if table_name is None:
table_name = cls._default_table
return f'{cls._project}.{cls.get_dataset()}.{table_name}'
@dataclass(frozen=True, eq=True)
class BilliardsUser(BQTransformer):
_dataset_wo_version = 'billiards_info'
_dataset_version = '20240830'
_default_table = 'users'
username: str
id: int
A = BilliardsUser(username='Philip', id=3)
B = BilliardsUser(username='James', id=7)
>>> [f.name for f in fields(A)]
['username', 'id']
>>> A.table()
'default-project-name.billiards_info_v20240830.users'
自 Python 3.6 字典开始维护插入顺序,自 Python 3.7 起,这已成为语言规范的一部分。
所以,如果这是您面临的问题,请按原样使用它。 通过查看示例代码,真的很难判断您有疑问的部分是什么。
一个旁注是,如果您不使用
@abstractmethod
,则没有理由使用 ABC
基础 - 它在最终代码中没有任何影响,但语义建议它 BQTransformer
应该不直接实例化(但这不会阻止这种情况)。