Python面向对象编程中__str__魔术方法未生效,仍返回<__main__.Card object>而非自定义字符串
嘿,你遇到的这个问题我之前也碰到过几次,看起来有点矛盾——明明写了__str__方法,直接调用x.__str__()能得到预期的字符串,但print(x)却还是输出<__main__.Card object at ...>这种默认格式对吧?别着急,咱们一步步排查原因:
最可能的几个原因及解决办法
1. __str__方法的缩进错了!
这是最容易踩的坑——你写的__str__方法根本没归到Card类里。比如如果你的代码是这样的:
class Card: def __init__(self): self.shape = "diamond" self.fill = random.choice(fill) self.number = random.choice(number) self.color = random.choice(color) # 这里缩进没对齐,__str__变成全局函数了! def __str__(self): return f"{self.number}-{self.color}-{self.fill}-{self.shape}.png"
这种情况下,Python根本不认这个__str__是Card类的方法,print(x)自然会调用object类的默认方法。你只要把__str__的缩进调整到和__init__同级就行。
2. 特殊方法名拼写错了
别笑,真的很容易手滑——比如把__str__写成__strr__、__st__甚至__repr__。Python对特殊方法名的要求是完全匹配,差一个下划线都不行,自然不会被自动调用。你再仔细核对一下你的方法名。
3. 代码里藏着未处理的异常
如果你的__str__方法内部抛出了异常,Python会自动“降级”调用__repr__方法(也就是那个默认的对象格式)。比如你代码里用到的fill、number、color这三个变量有没有提前定义?random模块有没有导入?
比如你得在代码开头加上这些:
import random # 得先定义这些可选值的列表,不然random.choice会报错 fill = ["solid", "striped", "open"] number = ["1", "2", "3"] color = ["red", "green", "blue"]
要是没这些,初始化Card实例的时候就会报错,或者某些属性没被正确赋值,__str__引用它们时就会抛出异常,最终导致print(x)显示默认格式。
4. 实例用的是旧版本的类
如果你是在交互式环境里调试,先定义了没有__str__的Card类,创建了x实例,然后才修改类加上__str__——这时候x还是旧类的实例,自然不会用新的__str__。这种情况只要重新创建x就行:x = Card()。
验证方案
把上面提到的点都检查一遍,然后运行完整的代码:
import random fill = ["solid", "striped", "open"] number = ["1", "2", "3"] color = ["red", "green", "blue"] class Card: def __init__(self): self.shape = "diamond" self.fill = random.choice(fill) self.number = random.choice(number) self.color = random.choice(color) def __str__(self): return f"{self.number}-{self.color}-{self.fill}-{self.shape}.png" x = Card() print(x) print(x.__str__())
这时候print(x)和print(x.__str__())应该会输出完全一样的内容啦。
内容的提问来源于stack exchange,提问作者Paris Shirley

