问题描述
A side effect of this question is that I was lead to this post, which states:
并暗示这是一件坏事.
但是,我之前以我认为是面向对象的方式使用过这样的代码.类似于以下内容:
However, I've used code like this before, in what I thought was an OO way. Something like the following:
class MyTime(object):
def __init__(self, h=0, m=0, s=0):
self.h = 0
self.m = 0
self.s = 0
def __iadd__(self, other):
if isinstance(other, MyTime):
self.h += other.h
self.m += other.m
self.s += other.s
elif isinstance(other, int):
self.h += other/3600
other %= 3600
self.m += other/60
other %= 60
self.s += other
else:
raise TypeError('Addition not supported for ' + type(other).__name__)
所以我的问题:
这是使用isinstance
"pythonic"和"good" OOP吗?
Is this use of isinstance
"pythonic" and "good" OOP?
推荐答案
一般而言.对象的接口应定义其行为.在上面的示例中,other
使用一致的接口会更好:
Not in general. An object's interface should define its behavior. In your example above, it would be better if other
used a consistent interface:
def __iadd__(self, other):
self.h += other.h
self.m += other.m
self.s += other.s
即使这看起来功能较少,但从概念上讲它要干净得多.现在,如果other
与接口不匹配,则将其留给语言以引发异常.您可以通过以下方式来解决加int
次的问题,例如-使用整数的接口"创建MyTime
个构造函数".这样可以使代码保持整洁,并为下一个人留下更少的惊喜.
Even though this looks like it is less functional, conceptually it is much cleaner. Now you leave it to the language to throw an exception if other
does not match the interface. You can solve the problem of adding int
times by - for example - creating a MyTime
"constructor" using the integer's "interface". This keeps the code cleaner and leaves fewer surprises for the next guy.
其他人可能会不同意,但是我觉得如果在特殊情况下(例如在实现插件体系结构时)使用反射,则isinstance
可能会有一个地方.
Others may disagree, but I feel there may be a place for isinstance
if you are using reflection in special cases such as when implementing a plugin architecture.
这篇关于isinstance pythonic/"good"的这种用法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!