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