如何使python类支持项目分配?

Jac*_*out 15 python inheritance built-in-types object-composition

在查看Think Complexity中的一些代码时,我注意到他们的Graph类为自己分配值.我已经从该类中复制了一些重要的行,并编写了一个示例类,ObjectChild但这种行为失败了.

class Graph(dict):
    def __init__(self, vs=[], es=[]):
        for v in vs:
            self.add_vertex(v)

        for e in es:
            self.add_edge(e)

    def add_edge(self, e):
        v, w = e
        self[v][w] = e
        self[w][v] = e

    def add_vertex(self, v):
        self[v] = {}

class ObjectChild(object):
    def __init__(self, name):
        self['name'] = name
Run Code Online (Sandbox Code Playgroud)

我确定不同的内置类型都有自己的使用方式,但我不确定这是否应该尝试构建到我的类中.有可能,怎么样?这是我不应该打扰的东西,而是依靠简单的构图,例如self.l = [1, 2, 3]?在内置类型之外应该避免吗?

我问,因为我被告知"你几乎不应该继承内置的python集合"; 建议我犹豫是否要限制自己.

为了澄清,我知道它ObjectChild不会"起作用",我可以很容易地使它 "工作",但我很好奇这些内置类型的内部工作方式使它们的界面与一个孩子不同object.

小智 11

在 Python 3 及更高版本中,只需将这些简单的函数添加到您的类中:

class some_class(object):
    def __setitem__(self, key, value):
        setattr(self, key, value)

    def __getitem__(self, key):
        return getattr(self, key)
Run Code Online (Sandbox Code Playgroud)


Cor*_*y D 9

他们通过继承来实现这种魔力dict.更好的方法是从UserDict或更新的collections.MutableMapping继承

你可以通过做同样的事情来完成类似的结果:

import collections

class ObjectChild(collections.MutableMapping):
    def __init__(self, name):
        self['name'] = name
Run Code Online (Sandbox Code Playgroud)

您还可以定义两个特殊函数,使您的类字典类似:__getitem__(self, key)__setitem__(self, key, value).您可以在Dive Into Python - Special Class Methods中看到这样的示例.

  • 我认为`UserDict`已经过时了(它来自于从`dict`继承是非法的日子).`MutableMapping`也不是提供项访问权的东西(它是[Abstract Base Class](http://docs.python.org/2/glossary.html#term-abstract-base-class)).如果要实现类似字典或列表的项目分配和访问,则需要编写(或继承)`__getitem__`和`__setitem__`方法. (2认同)

Fél*_*net 6

免责声明:我可能错了.

符号:

self[something]
Run Code Online (Sandbox Code Playgroud)

在Graph类中是合法的,因为它继承了dict.这种表示法来自词典ssyntax而不是来自类属性声明语法.

虽然与类关联的所有命名空间都是字典,但在类ChildObject中,self不是字典.因此,您无法使用该语法.

Otoh,在你的类Graph中,self是一个词典,因为它是一个图形,所有图形都是字典,因为它们继承自dict.


Ric*_*son 6

使用这样的东西好吗?

def mk_opts_dict(d):
    ''' mk_options_dict(dict) -> an instance of OptionsDict '''
    class OptionsDict(object):
        def __init__(self, d):
            self.__dict__ = d

        def __setitem__(self, key, value):
            self.__dict__[key] = value

        def __getitem__(self, key):
            return self.__dict__[key]

    return OptionsDict(d)
Run Code Online (Sandbox Code Playgroud)