使用 __repr__ 方法的意外递归循环
Unintended recursive loop with __repr__ method
我想显示一个实例的所有可访问属性的列表,所以我试试这个
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
为什么会这样?以及如何解决这个问题?
正如评论中指出的那样,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']
您可以使用 __str__
而不是 __repr__
来重载打印。
如果您必须使用 __repr__
,则使用 isinstance()
将属性值的类型与标准库中的 types.MethodType
进行比较。
我想显示一个实例的所有可访问属性的列表,所以我试试这个
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
为什么会这样?以及如何解决这个问题?
正如评论中指出的那样,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']
您可以使用 __str__
而不是 __repr__
来重载打印。
如果您必须使用 __repr__
,则使用 isinstance()
将属性值的类型与标准库中的 types.MethodType
进行比较。