虽然我来晚了9年,但是因为这个问题在我的搜索结果中排名第一...
关于:
此外,Python 3自动提供了一个repr()函数,所以我想我不需要重新定义它了(?)。那么str()呢?我知道它是对象的可读文本表示形式;我应该也定义它吗?有什么指导方针吗?
默认实现很好,直到它们不再好用(即,直到你需要更有用的东西)。
举个例子:
class Message:
_msg: str
def __init__(self, msg: str):
self._msg = msg
print(Message("asdf"))
print(str(Message("asdf")))
print(repr(Message("asdf")))
当然,缺省值是存在的,但是如果你有一些有用的信息需要打印到屏幕上、日志中等,那么使用<module.class object at address>
格式真的很有帮助吗?
与此相反...
class Message:
_msg: str
_urgent: bool
def __init__(self, msg: str, urgent:bool = False):
self._msg = msg
self._urgent = urgent
@classmethod
def urgent(cls, msg: str) -> "Message":
return cls(msg, urgent=True)
def __str__(self) -> str:
if not self._urgent:
return self._msg
return f"URGENT: {self._msg.upper()}"
def __repr__(self) -> str:
return f"{type(self).__name__}({self})"
print(Message("hey there!"))
print(str(Message("hey there!")))
print(str(Message.urgent("look behind you")))
print(repr(Message.urgent("look behind you")))
上面的建议,“如果不确定,就不要实现魔术方法。”部分正确(如果您不需要功能,为什么要实现它?),但它似乎也表明您可能不应该这样做。魔术方法实际上是用来被覆盖的 - 这是我们如何使用 Python 中“内置”的有用行为丰富我们的类,并避免许多其他必要的样板文件来序列化字符串、创建自定义迭代器或上下文管理器等。
__hash__
。如果您这样做,它们应该是不可变的,并且您必须同时实现__eq__
。 - user395760