良好的语义,子类或模拟?

时间:2011-05-10 09:39:49

标签: coding-style python

我已经使用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")

3 个答案:

答案 0 :(得分:3)

你在这里要问自己的关键问题是:

  

“如果'父级'班级改变,我的班级应如何改变?”

想象一下,dict中添加了一些新方法,您不会在UniqueDict中覆盖这些方法。如果您想表达 UniqueDict只是dict行为中的一个小推词,那么您继续继承您将自动更改基类。如果您想表示 UniqueDict有点像dict但实际上不是,那么您应该使用'仿真'模式

答案 1 :(得分:1)

子类化更好,因为您不必为每个单独的dict方法实现代理。

答案 2 :(得分:0)

我会选择子类,因为我会参考PEP 3119的动机:

  

例如,如果问'是这个对象   一个可变的序列容器?',一个   可以寻找'list'的基类,   或者可以找一个名为的方法   '的的GetItem '。但请注意,尽管如此   这些测试似乎都很明显   他们是正确的,就像一个人生成的那样   假阴性,另一个错误   阳性。

     

普遍认可的补救办法是   标准化测试,并将它们分组   进入正式的安排。这是   最容易通过关联完成   每个班级都有一套标准的可测试   属性,或者通过继承   机制或其他一些手段。每   测试随身携带一套   承诺:它包含了一个承诺   类的一般行为,和   对其他课程的承诺   方法将可用。

简而言之,有时希望能够使用isinstance检查映射属性。