2013-12-11 56 views
1

我想在我的python項目中保留一組字段名稱作爲別名(如'fieldName' = 'f')。雖然我敢肯定是最直接的方式是隻保留一個字典,像python中的別名字典,類與字典

F = {'_id'   :  '_id', 
    'tower'  :  'T', 
    'floor'  :  'F', 
    'pos'   :  'P' 
    } 

我想我可以只寫一個類一樣,

class F: 
    def __init__(): 
     self._id   =  '_id', 
     self.tower  =  'T', 
     self.floor  =  'F', 
     self.pos   =  'P' 

的唯一理由就是那麼我可以通過訪問數據,

get_var(f._id)這是短,更好看的比起來,

get_var(F['_id'])

如果我這樣做是濫用python嗎?有什麼優點或缺點?

這些別名將在啓動時從配置文件中讀取,並且不會通過運行時間進行更改。


編輯:

從塞拉斯的答案,我做了這個。與你的答案相比,這爲什麼會不好?

class Aliases: 
    """ Class to handle aliases for Mongo fields. 
     TODO: Should these be read off from a config file? 
    """ 

    def __init__(self): 
     self._F = { 
      '_id'   :  '_id', 
      'tower'  :  'T', 
      'floor'  :  'F', 
      'pos'   :  'P', 
      'stabAmplitude' : 's', 
      'totalEnergy' :  'z', 
      ... 
     } 

    def __getattr__(self, name): 
     """ Return the attributes from the alias dictionary instead of the 
      real attributes dictionary 
     """ 
     try: 
      return object.__getattribute__(self, '_F')[name] 
     except KeyError: 
      raise AttributeError('No attribute named %s.' % name) 

    def __setattr__(self, name, value): 
     """ No attributes should be changable """ 
     if name == '_F': 
      return object.__setattr__(self, name, value) 
     else: 
      raise AttributeError('Attribute %s cannot be changed.', name) 
+3

這不是「濫用」蟒蛇本身,但如果你只需要結構來存儲不是方法或有狀態的鍵值對,那麼只需使用一個字典。當訪問對象中的元素時,不要讓代碼更復雜,以便刪除一個或兩個字符。 – Will

+0

這不是關於字符長度。我覺得它看起來很醜陋,因爲這些名稱實際上是Python字典中的字段名稱(由'pymongo'返回)。所以一個普通的查詢看起來像'entry [F ['_ id']] vs'entry [F._id]'我覺得前者很混亂。 – xcorat

回答

3

你是什麼人以後可能(不常用AFAIK使用)是屬性字典

參見:https://pypi.python.org/pypi/attrdict

基本用法:

>>> from attrdict import AttrDict 
>>> d = AttrDict({"id": "foo"}) 
>>> d.id 
"foo" 

如果你真的很喜歡某些形式的別名屬性/字典式的訪問,則以下快速「N髒)OO類型代碼子類attrdict.AttrDict將工作:

from attrdict import AttrDict 


class AliasedAttrDict(AttrDict): 

    aliases = {} 

    def __getitem__(self, key): 
     if key in self.__class__.aliases: 
      return super(AliasedAttrDict, self).__getitem__(self.__class__.aliases[key]) 
     return super(AliasedAttrDict, self).__getitem__(key) 

    def __getattr__(self, key): 
     if key in self.__class__.aliases: 
      return super(AliasedAttrDict, self).__getitem__(self.__class__.aliases[key]) 
     return super(AliasedAttrDict, self).__getitem__(key) 


class MyDict(AliasedAttrDict): 

    aliases = { 
     "T": "tower", 
     "F": "floor", 
     "P": "pos" 
    } 


d = MyDict({"tower": "Babel", "floor": "Dirty", "pos": (0, 0)}) 
print d.tower 
print d.floor 
print d.pos 
print d.T 
print d.F 
print d.P 

輸出:

Babel 
Dirty 
(0, 0) 
Babel 
Dirty 
(0, 0) 
+0

雖然是對的。只需要使用普通的字典,幾乎沒有任何優勢可以削減*查找的單個字符*。但如果你真的需要/想要這個,可以使用'attrdict''。 –

+0

爲倡導pypi廣告重用代碼+1!打擊nih-syndrom! ;-) –

2

我只是使用的是全配置的代理對象,而不是一個變量名稱查找表(看起來像一個半措施對我來說)。

class VarMapProxy(object): 

    def __init__(self, proxied_call, **kwargs) 
     self.call = proxied_call 
     self.var_map = kwargs 

    def __getattr__(self, name): 
     try: 
      return self.call(self.var_map[name]) 
     except KeyError: 
      raise AttributeError('No attribute named %s.' % name) 

fields = VarMapProxy(get_var, id='_id', tower='T', floor='F', pos='P') 
fields.id # will return the result of get_var('_id') 
fields.pos # will return the result of get_var('P') 
+0

我不喜歡這樣。 a)它不是通用的b)它壞了。這是目前的形式不是一個好的整體解決方案;/ –

+0

我修復了我忘了的'return'。我也將其修改爲通用的,並將其從子類別代碼轉換爲包含字典,我認爲這更好。也是通用的。 –

+0

而'def'而不是'class' ... oi,一定是我回家的時候了。 –

1

更快,也許比創建一個類爲此目的更好 - 使用namedtuple。它有一個元組(我認爲)的內存消耗,但它更容易讀/命名處理屬性,而不是索引號

from collections import namedtuple 

F = namedtuple("F", "tower floor pos") 

f = F(tower=1, floor=2, pos=(1,4)) 

使用

f.tower 
Out[127]: 1 

f.floor 
Out[128]: 2 

f.pos 
Out[129]: (1, 4)