我还是Python的业余爱好者。
是否有可能看到python的注释扩展为什么? 例如,与数据类相关的错误,有时很难弄清楚它实际生成的代码。
例如:
@dataclass(order = True)
class Person:
name: str
age:int = 0
==
class Person:
def __init__(self, name:str, age=0):
self.name = name
self.age = age
def __repr__...
def __eq__(self, other):
return (self.name, self.age) == ( other.name, other.age)
或者,如果不可能的话,除了检查批注源代码之外,您通常如何找出它们的扩展范围?
例如,Racket具有强大的扩展宏机制,python是否具有等效功能?
答案 0 :(得分:1)
恐怕无法显示所需代码,因为数据类修饰是运行时更改。最好的办法是使用inspect.getsource,它将显示原始类,但不幸的是没有更改数据类:
>>> inspect.getsource(Person)
class Person:
name: str
age:int = 0
但是,尽管您的问题的答案是“不可能”,但以下内容可能会为您提供帮助。假设Person
是您的数据类,而SimplePerson
与Person
完全相同,但没有数据类修饰:
dir-在运行时获取对象的属性(包括方法)
>>> dir(SimplePerson)
['__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', 'age']
# looks just like a base object, plus 'age', which was not only declared, but also set
>>> dir(Person)
['__annotations__', '__class__', '__dataclass_fields__', '__dataclass_params__',
'__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'age']
# has some more attributes and methods that the dataclass decoration added
dis.dis-将对象的方法分解为字节码
>>> import dis
>>> dis.dis(SimplePerson)
# no output, there are no methods on an object that only has two class attributes
>>> import dis
>>> dis.dis(Person)
Disassembly of __eq__:
2 0 LOAD_FAST 1 (other)
2 LOAD_ATTR 0 (__class__)
4 LOAD_FAST 0 (self)
6 LOAD_ATTR 0 (__class__)
8 COMPARE_OP 8 (is)
10 POP_JUMP_IF_FALSE 36
3 12 LOAD_FAST 0 (self)
14 LOAD_ATTR 1 (name)
16 LOAD_FAST 0 (self)
18 LOAD_ATTR 2 (age)
20 BUILD_TUPLE 2
22 LOAD_FAST 1 (other)
24 LOAD_ATTR 1 (name)
26 LOAD_FAST 1 (other)
28 LOAD_ATTR 2 (age)
30 BUILD_TUPLE 2
32 COMPARE_OP 2 (==)
34 RETURN_VALUE
4 >> 36 LOAD_GLOBAL 3 (NotImplemented)
38 RETURN_VALUE
Disassembly of __ge__:
2 0 LOAD_FAST 1 (other)
2 LOAD_ATTR 0 (__class__)
4 LOAD_FAST 0 (self)
6 LOAD_ATTR 0 (__class__)
8 COMPARE_OP 8 (is)
10 POP_JUMP_IF_FALSE 36
3 12 LOAD_FAST 0 (self)
14 LOAD_ATTR 1 (name)
16 LOAD_FAST 0 (self)
18 LOAD_ATTR 2 (age)
20 BUILD_TUPLE 2
22 LOAD_FAST 1 (other)
24 LOAD_ATTR 1 (name)
26 LOAD_FAST 1 (other)
28 LOAD_ATTR 2 (age)
30 BUILD_TUPLE 2
32 COMPARE_OP 5 (>=)
34 RETURN_VALUE
4 >> 36 LOAD_GLOBAL 3 (NotImplemented)
38 RETURN_VALUE
Disassembly of __gt__:
2 0 LOAD_FAST 1 (other)
2 LOAD_ATTR 0 (__class__)
4 LOAD_FAST 0 (self)
6 LOAD_ATTR 0 (__class__)
8 COMPARE_OP 8 (is)
10 POP_JUMP_IF_FALSE 36
3 12 LOAD_FAST 0 (self)
14 LOAD_ATTR 1 (name)
16 LOAD_FAST 0 (self)
18 LOAD_ATTR 2 (age)
20 BUILD_TUPLE 2
22 LOAD_FAST 1 (other)
24 LOAD_ATTR 1 (name)
26 LOAD_FAST 1 (other)
28 LOAD_ATTR 2 (age)
30 BUILD_TUPLE 2
32 COMPARE_OP 4 (>)
34 RETURN_VALUE
4 >> 36 LOAD_GLOBAL 3 (NotImplemented)
38 RETURN_VALUE
Disassembly of __init__:
2 0 LOAD_FAST 1 (name)
2 LOAD_FAST 0 (self)
4 STORE_ATTR 0 (name)
3 6 LOAD_FAST 2 (age)
8 LOAD_FAST 0 (self)
10 STORE_ATTR 1 (age)
12 LOAD_CONST 0 (None)
14 RETURN_VALUE
Disassembly of __le__:
2 0 LOAD_FAST 1 (other)
2 LOAD_ATTR 0 (__class__)
4 LOAD_FAST 0 (self)
6 LOAD_ATTR 0 (__class__)
8 COMPARE_OP 8 (is)
10 POP_JUMP_IF_FALSE 36
3 12 LOAD_FAST 0 (self)
14 LOAD_ATTR 1 (name)
16 LOAD_FAST 0 (self)
18 LOAD_ATTR 2 (age)
20 BUILD_TUPLE 2
22 LOAD_FAST 1 (other)
24 LOAD_ATTR 1 (name)
26 LOAD_FAST 1 (other)
28 LOAD_ATTR 2 (age)
30 BUILD_TUPLE 2
32 COMPARE_OP 1 (<=)
34 RETURN_VALUE
4 >> 36 LOAD_GLOBAL 3 (NotImplemented)
38 RETURN_VALUE
Disassembly of __lt__:
2 0 LOAD_FAST 1 (other)
2 LOAD_ATTR 0 (__class__)
4 LOAD_FAST 0 (self)
6 LOAD_ATTR 0 (__class__)
8 COMPARE_OP 8 (is)
10 POP_JUMP_IF_FALSE 36
3 12 LOAD_FAST 0 (self)
14 LOAD_ATTR 1 (name)
16 LOAD_FAST 0 (self)
18 LOAD_ATTR 2 (age)
20 BUILD_TUPLE 2
22 LOAD_FAST 1 (other)
24 LOAD_ATTR 1 (name)
26 LOAD_FAST 1 (other)
28 LOAD_ATTR 2 (age)
30 BUILD_TUPLE 2
32 COMPARE_OP 0 (<)
34 RETURN_VALUE
4 >> 36 LOAD_GLOBAL 3 (NotImplemented)
38 RETURN_VALUE
Disassembly of __repr__:
352 0 LOAD_GLOBAL 0 (id)
2 LOAD_FAST 0 (self)
4 CALL_FUNCTION 1
6 LOAD_GLOBAL 1 (_thread)
8 LOAD_METHOD 2 (get_ident)
10 CALL_METHOD 0
12 BUILD_TUPLE 2
14 STORE_FAST 1 (key)
353 16 LOAD_FAST 1 (key)
18 LOAD_DEREF 0 (repr_running)
20 COMPARE_OP 6 (in)
22 POP_JUMP_IF_FALSE 28
354 24 LOAD_CONST 1 ('...')
26 RETURN_VALUE
355 >> 28 LOAD_DEREF 0 (repr_running)
30 LOAD_METHOD 3 (add)
32 LOAD_FAST 1 (key)
34 CALL_METHOD 1
36 POP_TOP
356 38 SETUP_FINALLY 12 (to 52)
357 40 LOAD_DEREF 1 (user_function)
42 LOAD_FAST 0 (self)
44 CALL_FUNCTION 1
46 STORE_FAST 2 (result)
48 POP_BLOCK
50 LOAD_CONST 0 (None)
359 >> 52 LOAD_DEREF 0 (repr_running)
54 LOAD_METHOD 4 (discard)
56 LOAD_FAST 1 (key)
58 CALL_METHOD 1
60 POP_TOP
62 END_FINALLY
360 64 LOAD_FAST 2 (result)
66 RETURN_VALUE
# not exactly readable, but here it is.. the code that dataclass added.