对于简单的键值存储,有关dicts vs对象的Python最佳实践是什么?

hug*_*omg 4 javascript python dictionary associative-array object

经过一段时间的Javascript编程后,我对对象和关联数组(字典)之间的二元性有了一点喜欢:

//Javascript
var stuff = { a: 17, b: 42 };

stuff.a;    //direct access    (good sugar for basic use)
stuff['a']; //key based access (good for flexibility and for foreach loops)
Run Code Online (Sandbox Code Playgroud)

在python中基本上有两种方法可以做这种事情(据我所知)

字典:

stuff = { 'a': 17, 'b':42 };

# no direct access :(
stuff['a'] #key based access
Run Code Online (Sandbox Code Playgroud)

或对象:

#use a dummy class since instantiating object does not let me set things
class O(object):
    pass

stuff = O()
stuff.a = 17
stuff.a = 42

stuff.a #direct access :)
getattr(stuff, 'a') #key based access
Run Code Online (Sandbox Code Playgroud)

编辑:一些答复还提到namedtuples作为buitin方法来创建不可变对象lighweight类.


所以我的问题是:

  1. 是否有使用dicts或对象存储简单的无方法键值对的既定最佳实践?

  2. 我可以想象有很多方法可以创建小帮助类来使对象方法不那么难看(例如,在构造函数上接收dict然后覆盖的东西__getattribute__).这是一个好主意还是我过度思考?

    • 如果这是一件好事,那么最好的方法是什么?此外,是否有任何优秀的Python项目使用我可能从中获取灵感的方法?

mil*_*ose 8

不确定"已建立的最佳实践",但我所做的是:

  1. 如果值类型是同质的 - 即映射中的所有值都是数字,请使用dict.
  2. 如果值是异构的,并且如果映射始终具有给定的或多或少恒定的键集,则使用对象.(最好使用实际的类,因为它闻起来很像数据类型.)
  3. 如果值是异质的,但映射中的键改变,则翻转硬币.我不确定这种模式经常出现在Python上,像这样的字典特别出现在Javascript中,用关键字参数"伪造"函数.Python已经有了这些,并且**kwargs是一个词典,所以我会选择dicts.

或者换句话说,用对象表示数据类型的实例.用dicts表示临时或临时映射.Swallow不得不使用['key']语法 - 让Python感觉像Javascript只是让我觉得被迫.


Rik*_*ggi 5

这将是我在 adict和 an之间决定object 用于存储简单的、无方法的键值对的方式

  1. 我需要迭代我的键值对吗?
    • 是:使用 dict
    • 否:转到 2。
  2. 我将拥有多少把钥匙?
    • 很多:使用 dict
    • 几个:去3。
  3. 键名重要吗?
    • 否:使用 dict
    • 是:转到 4。
  4. 我想一劳永逸地确定这个重要的关键名称吗?
    • 否:使用 dict
    • 是:使用 object

看看以下显示的差异可能也很有趣dis

>>> def dictf(d):
...     d['apple'] = 'red'
...     return d['apple']
... 
>>> def objf(ob):
...     ob.apple = 'red'
...     return ob.apple
... 
>>> dis.dis(dictf)
  2           0 LOAD_CONST               1 ('red') 
              3 LOAD_FAST                0 (d) 
              6 LOAD_CONST               2 ('apple') 
              9 STORE_SUBSCR         

  3          10 LOAD_FAST                0 (d) 
             13 LOAD_CONST               2 ('apple') 
             16 BINARY_SUBSCR        
             17 RETURN_VALUE         
>>> dis.dis(objf)
  2           0 LOAD_CONST               1 ('red') 
              3 LOAD_FAST                0 (ob) 
              6 STORE_ATTR               0 (apple) 

  3           9 LOAD_FAST                0 (ob) 
             12 LOAD_ATTR                0 (apple) 
             15 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)