良好的语义,子类还是模拟?
我已经使用Python有一段时间了,我很高兴在大多数形式中使用它,但我想知道哪种形式更Pythonic。模拟对象和类型是否正确,或者从这些类型进行子类化或继承是否更好?我可以看到两者的优点,也可以看到缺点。这样做的正确方法是什么?
子类化方法
class UniqueDict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
def __setitem__(self, key, value):
if key not in self:
dict.__setitem__(self, key, value)
else:
raise KeyError("Key already exists")
模拟方法
class UniqueDict(object):
def __init__(self, *args, **kwargs):
self.di = dict(*args, **kwargs)
def __setitem__(self, key, value):
if key not in self.di:
self.di[key] = value
else:
raise KeyError("Key already exists")
I have been using python for a while now and Im happy using it in most forms but I am wondering which form is more pythonic. Is it right to emulate objects and types or is it better to subclass or inherit from these types. I can see advantages for both and also the disadvantages. Whats the correct method to be doing this?
Subclassing method
class UniqueDict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
def __setitem__(self, key, value):
if key not in self:
dict.__setitem__(self, key, value)
else:
raise KeyError("Key already exists")
Emulating method
class UniqueDict(object):
def __init__(self, *args, **kwargs):
self.di = dict(*args, **kwargs)
def __setitem__(self, key, value):
if key not in self.di:
self.di[key] = value
else:
raise KeyError("Key already exists")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须问自己的关键问题是:
想象一下,新方法被添加到
dict
中,但您不会在UniqueDict
中重写这些方法。如果您想表达UniqueDict
只是dict
行为的一个小派生,那么您会选择继承,因为您将自动获得对基类的更改。如果您想表达UniqueDict
看起来像dict
但实际上不是,您应该使用 'emulation'模式。Key question you have to ask yourself here is:
Imagine new methods are added to
dict
which you don't override in yourUniqueDict
. If you want to express thatUniqueDict
is simply a small derivation in behaviour fromdict
's behaviour, then you'd go with inheritance since you will get changes to the base class automatically. If you want to express thatUniqueDict
kinda looks like adict
but actually isn't, you should go with the 'emulation' mode.子类化更好,因为您不必为每个字典方法实现代理。
Subclassing is better as you won't have to implement a proxy for every single dict method.
我会选择子类,因为我会参考 PEP 的动机第3119章
简而言之,有时希望能够使用
isinstance
检查映射属性。I would go for subclass, and for the reason I would refer to the motivation of PEP 3119:
In short, it is sometimes desirable to be able to check for mapping properties using
isinstance
.