1

我仍然是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 有没有等价的东西?

4

1 回答 1

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.
于 2019-08-02T13:13:22.740 回答