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

时间:2019-07-29 01:12:49

标签: python macros annotations data-class python-dataclasses

我还是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是否具有等效功能?

1 个答案:

答案 0 :(得分:1)

恐怕无法显示所需代码,因为数据类修饰是运行时更改。最好的办法是使用inspect.getsource,它将显示原始类,但不幸的是没有更改数据类:

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

但是,尽管您的问题的答案是“不可能”,但以下内容可能会为您提供帮助。假设Person是您的数据类,而SimplePersonPerson完全相同,但没有数据类修饰:

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.