Python 是";货柜;不是肾盂的?

Python 是";货柜;不是肾盂的?,python,dictionary,Python,Dictionary,假设我想使用一个类似于可变字典的对象在进程之间传递数据,但是我没有使用内置字典类型,而是创建了一个空的“Container”类,如下所示: class Container(object): pass x = Container() x.a = 42 x.b = ['Hitch', 'Hiker'] 现在,我可以使用x.a而不是写出x['a'],这对我来说似乎更清楚一些。假设我不希望在键值上循环,那么使用这个“容器”与标准字典相比,有没有什么我没有的主要缺点?是的,这是一个完美的pytho

假设我想使用一个类似于可变字典的对象在进程之间传递数据,但是我没有使用内置字典类型,而是创建了一个空的“Container”类,如下所示:

class Container(object):
  pass

x = Container()
x.a = 42
x.b = ['Hitch', 'Hiker']

现在,我可以使用
x.a
而不是写出
x['a']
,这对我来说似乎更清楚一些。假设我不希望在键值上循环,那么使用这个“容器”与标准字典相比,有没有什么我没有的主要缺点?

是的,这是一个完美的python方法。事实上是这样。

对于快速、简单的容器,我不认为这样做有什么错。主要的缺点是,您不能获得dict的所有其他方法(如
.get()
.items()
,等等),并且您的键必须是有效的Python标识符


请注意,还有一些库提供了类似的功能和更方便的功能(例如)。

恰恰相反;标准库的
argparse
模块中的
名称空间
类本质上就是这样一个容器(在您忽略了一些内部使用的魔法和私有方法之后)。

如果您想这样做,并且仍能获得字典的优势,我将子类
dict

class Container(dict):
    def __getattr__(self, name):
        return self[name]
    def __setattr__(self, name, value):
        self[name] = value


x = Container()

x.a = 42
x.b = ['Hitch', 'Hiker']

print(x)
印刷品:

{'b': ['Hitch', 'Hiker'], 'a': 42}

您可能希望单独处理现有属性,以便仍然可以更改它们:

def __setattr__(self, name, value):
    if name not in dir(self):
        self[name] = value
    else:
        super().__setattr__(name, value)

首先,所有键都必须是字符串。你不能说
x.[4,5,6]=5
@zondo我知道你的意思,但列表也不能是字典中的键。@zondo-true,但当我试图在进程之间传递属性时,因此,这与不能做
self没有什么不同。5=5
@nbubis你知道
namedtuple
吗?@L3viathan-
namedtuple
是不可变的,如问题中所述。非常好。您添加的最后一位的用途是什么?如果在普通字典上调用
dir
,您将看到它拥有的所有方法和属性。例如,如果您以后想要动态地更改
copy
方法,那么它在第一个版本中不起作用,因为它只会将它放在普通的字典存储中。(它也不可访问,因为
\uuu getattr\uuu
仅在缺少属性时才会被调用)。在大多数情况下,这并不重要。