我在codereview.se上有一个名为WeakBoundMethod(source的类)。我想了解一下如何实施__hash__()
的指导原则。此外,Python 3自动提供__repr__()
函数,所以我想我不应该费心去重新定义它(?)。那么__str__()
怎么样,我理解的是对象的人类可读文本表示;我也应该定义它吗?任何指导方针?
关于散列函数...
我希望它根据它包装的绑定方法的__self__
和__func__
生成哈希。我怎样才能做到这一点?
答案 0 :(得分:2)
如果有疑问,请不要实施魔术方法。默认是有原因的,并且没问题。在您的情况下,完全没有必要实现__hash__
(如果您要实现它,您还必须实现__eq__
),除非您希望有人拥有方法集或字典。< / p>
__str__
可能很有用。在您的情况下,其结果应包括:
str()
结果用于标识函数,例如,按名称答案 1 :(得分:0)
聚会晚了9年,但是对于我来说,这才是搜索结果的顶部...
关于:
此外,Python 3自动提供了 repr ()函数,所以我想我应该再为它重新定义(?)。关于 str (),我理解的是对象的人类可读文本表示形式;我也应该定义吗?有任何准则吗?
除非没有,否则默认的实现是好的(例如,直到您想要更有用的东西为止)。
关键点:
class Message:
_msg: str
def __init__(self, msg: str):
self._msg = msg
# ... other custom behavior that makes this more useful than just a string
print(Message("asdf")) # '<__main__.Wat object at 0x104a99128>'
print(str(Message("asdf"))) # '<__main__.Wat object at 0x104a991d0>'
print(repr(Message("asdf"))) # '<__main__.Wat object at 0x104a991d0>'
当然,存在默认值,但是如果您有一些有助于打印到屏幕,日志等的内容,<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})"
# ... other custom behavior that makes this more useful than just a string
print(Message("hey there!")) # hey there!
print(str(Message("hey there!"))) # hey there!
print(str(Message.urgent("look behind you"))) # URGENT: LOOK BEHIND YOU
print(repr(Message.urgent("look behind you"))) # Message(URGENT: LOOK BEHIND YOU)
以上建议“如果有疑问,请不要实施魔术方法。”是部分正确的(如果您不需要功能,为什么要实现它?),但这似乎也表明您可能不需要。魔术方法实际上是要被覆盖的-这是我们通过在Python中“内置”的有用行为来丰富我们的类,并避免了很多其他必要的样板化序列化为字符串,创建自定义迭代器或上下文管理器等。>