TLDR:这是一个关于在 Python 中编写常见需求的最佳方法的具体问题,即创建非平面“类型” - 恕我直言(作为 3 年中级 Python 开发人员)可能是我遇到的“如何做”的最大问题我在 Python 中很容易做到这一点。
对于版主:我在底部确实有特定的代码和问题:D
背景
假设我正在编写一些代码并且我需要一个非原始变量类型:
所以在元代码中,我想在我的代码中定义它以供以后使用:
MyType = type {
mouth: bool
nose: string
}
现在假设我需要的变量类型不是“平面”:
MyType = type {
mouth: bool
nose: string
hair: {
color: string
length: float
}
}
现在假设我希望能够轻松(语法)创建实例和引用属性(再次,元代码):
anInstance = MyType(
mouth=True,
nose='big',
hair=(color='red', length=5.5)
)
if anInstance.mouth {
print('has a mouth, and hair is', anInstance.hair.color)
}
所以可以说我的第一个要求是必须有要求:
- 轻松声明非平面类型
注意 - 目标/要求是一次性定义非平面类型 - 不使用单独定义所有成员然后组合最终类型的组合
现在让我们也说我想要 - 不是必须拥有的,而是真的喜欢 - 在我的代码中完成的另外两件事很好有要求:
- 在运行类型检查属性类型的正确性
- 限制我的类型,所以我不能随意添加新属性
所以:
anInstance.nose = 5.5 # -> this tells me when it runs that it's Bad - wrong type
anInstance.chin = 'hairy' # -> Bad too - this attribute isn't declared in the definition
问题
我的观点和经验:上述概念(声明非平面类型......也可能带有属性类型和定义强制)在python中并不容易
我所说的“不容易做到”的意思是
- 没有单一的标准方法可以做到这一点
- 在大多数python类/教程等中,它并没有被很多/很好/早期覆盖——尽管恕我直言,这是一个非常常见的代码结构要求
然而,在许多(大多数?)其他语言中,上述要求——尤其是(1)(非平面复合类型)在语法和概念上都很容易。
...我知道有些人会默认回复:
- python是鸭子类型的,所以处理它
- 做个男人,用类工厂自己写
- 只需使用我最喜欢的模块/功能/元类模板模型 X、Y 或 Z 或 ...*
- 只需使用字典,然后使用点'。' 属性引用。
- 只需使用递归嵌入的 lambda 定义的默认字典
- …………
...所有正确的观点 - 但我仍然认为对上述内容的需求并不完全存在,大量不同的做事方式是一个问题,并且没有解释如何在许多初学者/中级中做类型指南,即使(IHMO)它是应用程序中的常见用例需求
不是真正的好解决方案
dataclass
我可以通过在 a 中嵌入 a 轻松满足要求(1)dataclass
:
@dataclass
class MyType:
@dataclass
class HairType:
color: str
length: float
mouth: bool
nose: str
hair: HairType
同样,我可以使用嵌入式命名元组。我还可以使用任意数量的模块(marshmellow、pydantic、...、...)。
但是 - 再次 - 我的论点/观察 - 这并不简洁和简单(因为它可能/应该是?),并且有 X 不同的方法来做到这一点,即使(恕我直言)这是一个共同的要求。
问题
- 对于上述类型定义,(以及可选的属性检查目标)人们使用什么方法?...不同选项的优缺点是什么?
- 有没有办法在python中以一种非常简单、简洁的方式完成上述操作——尤其是要求(1)?
- 我一个人在想a)这是一个常见的要求,b)在Python中做起来并不快速和容易(与其他一些语言相比)