【问题标题】:Unintended recursive loop with __repr__ method使用 __repr__ 方法的意外递归循环
【发布时间】:2019-12-05 11:22:21
【问题描述】:

我想显示一个实例的所有可访问属性的列表,所以我试试这个

class Test:
    a=2     #initializing some attribute
    b=1     #initializing some attribute
    def some_method(self):
        attr=[]                 
        for k in [i for i in dir(self) if not i.startswith('__')]:
            attr.append(f'{k}={getattr(self,k)}')      #to collect all attributes and their values pair
        return attr
    def __repr__(self):                                #because i want to overload print behavior
        return str(self.some_method())
some_instance=Test()
print(some_instance) 

它返回了一个错误:

RecursionError: maximum recursion depth exceeded while calling a Python object

为什么会这样?以及如何解决这个问题?

【问题讨论】:

  • 如果你的对象中有一个循环(例如列表包含对self的引用,或者其中一个元素以某种方式旨在打印self),那么你会进入递归循环。
  • @WillemVanOnsem a,b,some_method 是我在实例中拥有的所有东西,是哪一个导致了这个问题?
  • @TuanDoan:通常dir 不仅有这些属性。例如some_method 等。Test().some_methodrepr(..)<bond method Test.some_method of repr(self)),因此是递归的,所以Test().some_methodrepr(..) 会导致对repr(self) 的新调用。

标签: python recursion repr


【解决方案1】:

正如 cmets 中所指出的,repr(Test().some_method) 调用它所在对象的 repr,产生一个永无止境的子父repr 方法调用堆栈。 如果您对显示可调用成员不感兴趣,可以将它们过滤掉,这样他们就不会被要求成为字符串的一部分:

class Test:
    a=2     #initializing some attribute
    b=1     #initializing some attribute
    def some_method(self):
        attr=[]                 
        for k in dir(self):
            val = getattr(self, k)
            if not k.startswith('__') and not callable(val):
                attr.append(f'{k}={val}')      #to collect all attributes and their values pair
        return attr
    def __repr__(self):                                #because i want to overload print behavior
        return str(self.some_method())
some_instance=Test()

然后print(some_instance) 显示

['a=2', 'b=1']

【讨论】:

    【解决方案2】:

    您可以使用__str__ 代替__repr__ 来重载打印。 如果您必须使用__repr__,则使用isinstance() 将属性值的类型与标准库中的types.MethodType 进行比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-30
      • 2023-03-14
      • 1970-01-01
      • 2017-02-28
      • 1970-01-01
      • 2020-10-01
      • 2017-09-15
      • 1970-01-01
      相关资源
      最近更新 更多