python中的别名字典,Class vs dict

时间:2013-12-11 23:50:35

标签: python alias

我想在我的python项目中保留一组字段名称作为别名(如'fieldName' = 'f')。虽然我很确定最直接的方法就是保持一个字典,比如

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 个答案:

答案 0 :(得分:3)

你可能追求的是什么(不常用的afaik )是属性词典

请参阅:https://pypi.python.org/pypi/attrdict

基本用法:

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

如果你真的喜欢某种形式的别名属性/字典式访问,那么以下 quick'n dirty )OO风格的代码子类化{{1}将工作:

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

答案 1 :(得分:2)

我只是使用一个完整的可配置代理对象而不是var名称查找表(对我来说似乎是一个半度量)。

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')

答案 2 :(得分: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)