考虑下面的类:
@dataclass
class Point:
id: int
x: int
y: int
@property
def distance_from_zero(self): return (self.x**2 + self.y**2)**0.5
color: tuple #RGB or something...
我知道我可以从 __annotations__
变量,或从 dataclasses.fields
井然有序。我也知道任何对象的常规方法都可以用 dir
或者使用 __dict__
方法。
但我所追求的是能够以正确的顺序给我两者的东西,在上面的例子中,它会是这样的:
>>>get_all_fields(Point)
['id', 'x', 'y', 'distance_from_zero', 'color']
我唯一能想到的就是使用 inspect
模块读取实际代码并以某种方式找到顺序。但这听起来真的很恶心。
2条答案
按热度按时间ctzwtxfj1#
您声明希望避免使用检查,但据我所知,这将是唯一干净的解决方案。其他任何东西都注定是不准确、不可靠或麻烦的。
看这里,使用
inspect.getsource
还有一点习俗ast
节点漫游器:使用此解决方案意味着您不必更改
Point
为了得到你想要的东西,你可以用任何方式上课。mxg2im7a2#
这是迄今为止我发现的最好的解决方法,其思想是在创建类时
__annotations__
对象将开始逐个填充,因此一个选项是在创建类期间跟踪属性。它并不完美,因为它迫使您使用替代的装饰器而不是属性,而且它也不能对函数方法执行同样的操作(但我现在不关心这一点)。在我的实现中,您还必须装饰整个类,以便附加一个classmethod
它实际上输出命令。问题中的例子必须改为:
最后,输出是这样的:
(我不会把它标记为答案,因为它有一个脚印,并且不考虑类中的可调用方法)