python 的注释(例如数据类)可以扩展到它生成的代码中吗?

Can python's annotation (e.g dataclass) be expanded into the code it produces?

我在 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 有类似的东西吗?

恐怕无法按您的意愿显示代码,因为数据class 修饰是运行时更改。您可以做的最好的事情是使用 inspect.getsource,它将显示原始的 class,不幸的是没有数据 class 更改:

>>> inspect.getsource(Person)
class Person:
   name: str
   age:int = 0

虽然您的问题的答案是 "It's not possible",但也许以下内容可以帮助您。给定 Person 这是您的数据 class,而 SimplePerson 与没有数据 class 修饰的 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.