2011-05-22 57 views
14

当使用Python字典(字典)键,似乎有几个常用的方法:什么是字典词典键常量的Python最佳实践?

  1. some_dict['key_name'] # string constants everywhere

  2. some_dict[KeyConstants.key_name] # where class KeyConstants: key_name: 'key_name'

  3. some_dict[KEY_NAME] # with from some_module import KEY_NAME # a module level constant

    1. “KEY_NAME '的缺点是你重复consta遍及你的代码。这不是干的。更糟糕的是,如果您曾经发布过API(从最广泛的意义上说),那么您的API会让消费者在任何地方重复使用这些常量,如果您想将“key_name”更改为“better_key_name”,这将是一个突破性更改。

    2. 这是键入语言DRY方法,常量合并在一个地方。它唯一的缺点是它很丑,可读性较差,而且比较冗长。 Pythonic原则主要禁止这一点。它允许您轻松更改表示键的常量,因为每个人都对变量KeyConstants.key_name进行编码。它也适用于IDE进行重构。

    3. 在PEP 8风格指南中推荐使用模块级别的常量。 ALL_CAPS_ARE_LOUD,难以输入。这有一些的这两个选项优点1和2

什么是字典键常量其他一些最佳做法?上述哪种方法是首选,何时?

+2

为什么有这么多恒定的钥匙呢?为什么不使用模块级别的变量或类似于记录的对象来保存属性? – delnan 2011-05-22 14:42:38

+5

如果键是可变的,那么字典是很好的,否则你可以在一个类上使用命名的元组或属性。使用常量键应该是一个非常罕见的场合。使用JSON时或与数据库/存储nosql的无ORM处理(例如pymongo而不MongoEngine) – 2011-05-22 15:06:39

+3

连键问题的字典是极为普遍的。虽然你可以用字典的键成类与属性,你就结束了一堆难看的包装/拆包管道代码,如果基础数据字典开始。 – velshin 2011-05-22 19:36:09

回答

3
  1. d [ 'KEY_NAME']
  2. d [Keys.key_name]
  3. d [KEY_NAME]

我真的不查看#3为需要模块级进口;他们只是可以在模块namepsace中,例如你可以做类似How to programmatically set a global (module) variable?

#2优于#1的优点是,错别字和过时的值会引发属性错误“此密钥不存在!”而不是索引错误“找不到!” - 这是总是更好。 #2>#1。这也不是更详细的,因为如果你打字很多,你只需设置K=Keys(或其他),所以你有d[K.key_name],只有两个字符多()。例如,根据之前怎么我的感觉,我可能会做或者:

import subprocess as proc 
proc.Popen(..., stdout=proc.PIPE) 

import subprocess as proc 
PIPE = proc.PIPE 
proc.Popen(..., stdout=PIPE) 

from subprocess import * 
Popen(..., stdout=PIPE) 

至于#3,ALL_CAPS_ARE_LOUD是有原因的;区分d[someVariable](其可以保持任何关键字)和d[magicKeyword] - 而d[MAGIC_KEYWORD]明确表示它是常数,而不是一些可能保持常数的变量(例如, for someVariable in magicKeywords。#3基本上相当于到#2,例如re.DOTALLre相当于KeyConstants,而不必记住KeyConstants容器的名称,因为它的模块)。因此#3优于#2,除非你处于一种奇怪的情况,你有不同类型的密钥空间。

DRY/OAOO是非常非常重要的,但最终是不相关的任何这些,因为你总是需要以引用它重复一个变量名;你可以做的最好的是创建一个别名。

你也可以考虑#4,这是赋予你的字典与属性,例如d.key_name - 这只适用于某些可自订的对象。

但引述由Jochen Ritzel评论:“使用常数键应该是一个非常难得的机会”(使用对象的属性,或者他也许暗示了一个名为元组,虽然我总是发现他们笨拙)

+1

谢谢你的深思。请注意,对于NAMED_CONSTANTS中的任何一个,我们都在干这个常量的值;这适用即使他们是钥匙。当您的密钥映射到json或数据库时,为什么字典密钥名称和NAMED_CONSTANT_KEY可以独立变化,这变得更加清晰。 – velshin 2011-05-22 16:54:32

1

这是一个老问题,但你签出Bunch?它是一个支持属性风格访问的字典,一个JavaScript。

>>> from bunch import bunchify 
>>> from bunch import unbunchify 
>>> import datetime as dt 

>>> my_dict = {'a': 'a', 'b': [{'c': 'c', 'n': 1}, {'c': 'k', 'n': 2}], 'dt': dt.datetime.utcnow()} 

>>> my_dict_obj = bunchify(my_dict) 
>>> my_dict_obj.b[0].c 
'c' 
>>> 'a' in my_dict_obj 
True 
>>> 'x' in my_dict_obj 
False 
>>> my_dict = unbunchify(my_dict_obj)