如何检查对象是否实现了__str__方法

12

如果对象没有实现__str__方法,我想动态地在对象上实现它。

我尝试使用hasattr(obj, '__str__'),但它总是返回true,因为它从对象类中找到了它。

有没有一种方法可以确定一个对象是否实际实现了__str__

我知道可以使用inspect.getmembers(obj),但我正在寻找更具Python风格的方式。

编辑

class Employee(object):
def __init__(self, name, age, emp_code):
    self.name = name
    self.age  = age
    self.emp_code = emp_code

测试

e = Employee("A", 23, "E1")
print hasattr(e, '__str__')
>> True

我想要一个检查,返回False而不是继承自object的方法。


2
检查obj.__str__ != object.__str__是否足够? - Gabe
1
你想让这个方法适用于任何继承的__str__方法吗?如果该方法不是来自于object,而是继承链上的其他类呢? - reem
1
动态实现 __str__ 看起来非常可疑。你是如何/为什么这样做的? - Eevee
4
我希望你知道,你不能将特殊方法添加到现有对象上;Python不会在实例的字典中检查特殊方法的查找。 - user2357112
为什么不直接正常实现__repr__呢?这基本上就是它的作用。 - Eevee
显示剩余6条评论
5个回答

17

由于您想要检查的是是否有一个实现了__str__方法,而不是默认的object.__str__方法。因此,你可以这样做:

Foo.__str__ is not object.__str__

要检查实例对象,您需要在类上进行检查:

type(f).__str__ is not object.__str__

即使Foo没有直接实现__str__,而是从另一个类继承了它,而这似乎是您想要的,这个方法也可以正常运行。


2
需要使用 type(f).__dict__['__str__'] 来避开继承。嗯,dunder 方法。 - Eevee
尽管它仍然没有回答为什么 hasattr(obj, '__eq__') 可以正常工作而 hasattr(obj, '__str__') 失败了。 - Bhushan
2
不能在对象上实现特殊方法,只能在它们的类上实现。 - Eevee
哦,明白了... setattr(obj.class, 'str', lambda x: "new String") - Bhushan
1
@Bhushan:在这种情况下最好不要对对象执行str(),而是自己编写方法。 - Lennart Regebro
显示剩余10条评论

1
任何继承自object基类的对象都将拥有一个__str__方法,因此测试其是否存在是可以忽略不计的。
您可以在对象上存储一个标志属性,然后测试该属性即可:
if not getattr(obj, 'has_str_override_flag'):
    override_str_here(obj)
    setattr(obj, 'has_str_override_flag', True)

0

在你的对象中,有一个__dict__包含了对象拥有的所有方法和变量。你可以通过以下方式检查给定对象是否实现了__str__()方法:

'__str__' in Employee.__dict__

或者

'__str__' in vars(Employee)

vars()和__dict__之间没有区别,只是vars()更符合Python语言的风格。


0
原来内置类型依赖于object.__str__进行智能格式化。我只是想消除无用的字符串,比如<__main__.Foo object at 0x10299d390>,并仍然正确打印dict和其他类型。我的解决方案:
objre = re.compile(r"<.* object at 0x[0-9a-f]+>")
if objre.fullmatch(str(obj)):
    # Do smarter formatting

这不会捕获模块、函数等的默认格式,但可以通过inspect.getsource()显示源代码,但无论如何我都不会在变量检查器中显示它们。


0
使用type(e).__dict__.get(method_name)可以避免在使用type(e).__dict__[method_name]时,如果method_name不存在于类中而导致的KeyError。
e = Employee("A", 23, "E1")
if type(e).__dict__.get('__str__'):
    print('__str__ implemented')
else:
    print('__str__ not implemented')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接