良好的语义,子类还是模拟?

发布于 2024-11-05 19:30:27 字数 763 浏览 0 评论 0原文

我已经使用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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

送君千里 2024-11-12 19:30:27

您必须问自己的关键问题是:

“如果‘父’类发生变化,我的类应该如何变化?”

想象一下,新方法被添加到 dict 中,但您不会在 UniqueDict 中重写这些方法。如果您想表达 UniqueDict 只是 dict 行为的一个小派生,那么您会选择继承,因为您将自动获得对基类的更改。如果您想表达 UniqueDict 看起来像 dict 但实际上不是,您应该使用 'emulation'模式。

Key question you have to ask yourself here is:

"How should my class change if the 'parent' class changes?"

Imagine new methods are added to dict which you don't override in your UniqueDict. If you want to express that UniqueDict is simply a small derivation in behaviour from dict's behaviour, then you'd go with inheritance since you will get changes to the base class automatically. If you want to express that UniqueDict kinda looks like a dict but actually isn't, you should go with the 'emulation' mode.

娜些时光,永不杰束 2024-11-12 19:30:27

子类化更好,因为您不必为每个字典方法实现代理。

Subclassing is better as you won't have to implement a proxy for every single dict method.

橘香 2024-11-12 19:30:27

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

例如,如果询问“这是这个对象吗?”
可变序列容器?',一个
可以寻找“列表”的基类,
或者可以寻找一种名为
'获取项目'。但请注意,虽然
这些测试可能看起来很明显,但也不是
其中是正确的,因为生成
假阴性,以及其他假阴性
积极的一面。

普遍同意的补救措施是
标准化测试并将其分组
进入正式安排。这是
最容易通过与
每个班级有一套可测试的标准
属性,或者通过继承
机制或其他方式。每个
测试带有一组
承诺:它包含有关的承诺
班级的一般行为,以及
关于其他类别的承诺
方法将可用。

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

I would go for subclass, and for the reason I would refer to the motivation of PEP 3119:

For example, if asking 'is this object
a mutable sequence container?', one
can look for a base class of 'list',
or one can look for a method named
'getitem'. But note that although
these tests may seem obvious, neither
of them are correct, as one generates
false negatives, and the other false
positives.

The generally agreed-upon remedy is to
standardize the tests, and group them
into a formal arrangement. This is
most easily done by associating with
each class a set of standard testable
properties, either via the inheritance
mechanism or some other means. Each
test carries with it a set of
promises: it contains a promise about
the general behavior of the class, and
a promise as to what other class
methods will be available.

In short, it is sometimes desirable to be able to check for mapping properties using isinstance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文