gaogaotiantian / objprint

A library that can print Python objects in human readable format
Apache License 2.0
510 stars 43 forks source link

在面对Enum对象时,输出的结果不符合预期。 #60

Closed Sclock closed 2 years ago

Sclock commented 2 years ago

测试代码:

from enum import Enum
from objprint import op,add_objprint

class temp_a(Enum):
    a = 1

@add_objprint
class temp_b(Enum):
    b = 1

print("temp_a:\n",temp_a,"\n")

print("temp_a.a:\n",temp_a.a,"\n")

print("op_temp_a:")
op(temp_a)
print("\n")

print("op_temp_a.a:")
op(temp_a.a)
print("\n")

print("================================================================\n")

print("temp_b:\n",temp_b,"\n")

print("temp_b.b:\n",temp_b.b,"\n")

print("op_temp_b:")
op(temp_b)
print("\n")

print("op_temp_b.b:")
op(temp_b.b)
print("\n")

输出:

temp_a:
 <enum 'temp_a'> 

temp_a.a:
 temp_a.a

op_temp_a:
<enum 'temp_a'>

op_temp_a.a:
temp_a.a

================================================================

temp_b:
 <enum 'temp_b'>

temp_b.b:
 <temp_b 0x24a740c2ee0
  .__objclass__ = <enum 'temp_b'>,
  ._name_ = 'b',
  ._value_ = 1
>

op_temp_b:
<enum 'temp_b'>

op_temp_b.b:
<temp_b 0x24a740c2ee0
  .__objclass__ = <enum 'temp_b'>,
  ._name_ = 'b',
  ._value_ = 1
>

符合直觉的结果应该是:

class temp_a(Enum):
    a = 1
op(temp_a)

输出:

 <temp_a 0xFFFFFFFF
  .__objclass__ = <enum 'temp_a'>,
  .temp_a.a = < xxxxxxx
      ._name_ = 'b',
      ._value_ = 1
  >
>
gaogaotiantian commented 2 years ago

op(temp_a)是不可能输出temp_a的,因为temp_a是个class(type),而<temp_a ..>的形式打印的应该是个temp_aobject,这里明显不应该混淆。

@add_objprint也是一个道理,它改变的是object的输出,而不是class本身。

就像下面的代码:

class A:
    def func(self):
        pass
op(A)
op(A())

你觉得打印的内容应该一样么……

还有,当你op一个自己定义了__str__的object的时候,op的默认behavior是尊重它的__str__,而class本身是个typeobject,type是有自己的__str__函数的。如果你想用op,你可以op(temp_a, honor_existing=False),就会看到一大串东西。

依然,它打印的是一个class,也就是type,而不是它的object。

Sclock commented 2 years ago

好的 受教了