对于自定义 Python 类来说,哪个更好 __repr__ ?
似乎 __repr__ 函数可以通过不同的方式返回。
我有一个 InfoObj 类,它存储了很多东西,其中一些我并不特别希望该类的用户自己设置。我认识到 python 中没有任何内容受到保护,他们可以直接潜入并设置它,但似乎在 __init__ 中定义它使得更有可能有人看到它并认为将它传递进去就可以了。
(示例:当验证函数确定对象已完全填充时,由验证函数设置布尔值;当存储了足够的信息时,从其他值计算出值...例如 A = B + C,因此一旦 A和 B 被设置,然后 C 被计算并且对象标记为 Valid=True。)
因此,考虑到所有这些,设计 __ repr__ 输出的最佳方法是什么?
bob = InfoObj(Name="Bob")
# Populate bob.
# Output type A:
bob.__repr__()
'<InfoObj object at 0x1b91ca42>'
# Output type B:
bob.__repr__()
'InfoObj(Name="Bob",Pants=True,A=7,B=5,C=2,Valid=True)'
# Output type C:
bob.__repr__()
'InfoObj.NewInfoObj(Name="Bob",Pants=True,A=7,B=5,C=2,Valid=True)'
...类型 C 的要点是不愉快地将我在 C++ 中设置为“私有”的所有内容作为构造函数的参数,并让使用该类的队友使用接口函数来设置它,即使这需要更多工作对于他们来说。在这种情况下,我将定义一个不接受某些内容的构造函数,以及一个稍微难以注意到的单独函数,用于 __repr__
如果有任何区别,我计划存储这些数据库中的 python 对象使用其 __repr__
输出并使用 eval()
检索它们,至少除非我想出更好的方法。队友手动创建完整对象而不是通过正确的接口函数的结果是,一种类型的信息检索可能不稳定,直到有人弄清楚他做了什么。
It seems there are different ways the __repr__
function can return.
I have a class InfoObj that stores a number of things, some of which I don't particularly want users of the class to set by themselves. I recognize nothing is protected in python and they could just dive in and set it anyway, but seems defining it in __init__
makes it more likely someone might see it and assume it's fine to just pass it in.
(Example: Booleans that get set by a validation function when it determines that the object has been fully populated, and values that get calculated from other values when enough information is stored to do so... e.g. A = B + C, so once A and B are set then C is calculated and the object is marked Valid=True.)
So, given all that, which is the best way to design the output of __ repr__?
bob = InfoObj(Name="Bob")
# Populate bob.
# Output type A:
bob.__repr__()
'<InfoObj object at 0x1b91ca42>'
# Output type B:
bob.__repr__()
'InfoObj(Name="Bob",Pants=True,A=7,B=5,C=2,Valid=True)'
# Output type C:
bob.__repr__()
'InfoObj.NewInfoObj(Name="Bob",Pants=True,A=7,B=5,C=2,Valid=True)'
... the point of type C would be to not happily take all the stuff I'd set 'private' in C++ as arguments to the constructor, and make teammates using the class set it up using the interface functions even if it's more work for them. In that case I would define a constructor that does not take certain things in, and a separate function that's slightly harder to notice, for the purposes of __repr__
If it makes any difference, I am planning to store these python objects in a database using their __repr__
output and retrieve them using eval()
, at least unless I come up with a better way. The consequence of a teammate creating a full object manually instead of going through the proper interface functions is just that one type of info retrieval might be unstable until someone figures out what he did.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
__repr__
方法旨在为开发人员(而不是最终用户)生成最有用的输出,因此只有您才能真正回答这个问题。然而,我通常会选择选项 B。选项 A 不是很有用,而选项 C 则不必要地冗长——无论如何,你都不知道你的模块是如何导入的。其他人可能更喜欢选项 C。但是,如果您想将 Python 对象存储在数据库中,请使用
pickle
。如果您使用的是较旧的 Python(3.x 之前的版本),请注意
cPickle
速度更快,但pickle
更具可扩展性。 Pickle 无需任何配置即可在您的某些类上工作,但对于更复杂的对象,您可能需要编写自定义 picklers。The
__repr__
method is designed to produce the most useful output for the developer, not the enduser, so only you can really answer this question. However, I'd typically go with option B. Option A isn't very useful, and option C is needlessly verbose -- you don't know how your module is imported anyway. Others may prefer option C.However, if you want to store Python objects is a database, use
pickle
.If you're using older Python (pre-3.x), then note that
cPickle
is faster, butpickle
is more extensible. Pickle will work on some of your classes without any configuration, but for more complicated objects you might want to write custom picklers.