Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的别名字典,类vs dict_Python_Alias - Fatal编程技术网

python中的别名字典,类vs dict

python中的别名字典,类vs dict,python,alias,Python,Alias,我想在python项目中保留一组字段名作为别名(如'fieldName'='f')。虽然我很确定最直接的方法就是保持口述,比如 F = {'_id' : '_id', 'tower' : 'T', 'floor' : 'F', 'pos' : 'P' } 我想我可以写一个类,比如 class F: def __init__():

我想在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.\u id)

get_var(F[''u 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)

您可能想要的(不是常用的afaik)是一个属性字典

见:

基本用法:

>>> from attrdict import AttrDict
>>> d = AttrDict({"id": "foo"})
>>> d.id
"foo"
如果您真的想要某种形式的别名属性/目录样式访问,那么下面的快速(脏)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)

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


比为此目的创建一个类(使用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)

这并不是在“滥用”python本身,但如果您只需要该结构来存储非方法或非有状态的键值对,那么只需使用dict即可。在从对象访问元素时,不要让代码变得更复杂,而要去掉一两个字符。这与字符长度无关。我觉得它看起来很难看,因为这些名称实际上是python字典上的字段名(由
pymongo
返回)。因此,一般的查询看起来像
entry[F[''u id']]
vs
entry[F.\u id]
我觉得前者令人困惑。不过威尔是对的。仅仅使用一本普通的字典,几乎没有任何优势是为了查找而删去一个字符。但是如果你真的需要/想要它,
attrdict
就是要使用的东西。+1用于提倡pypi ad代码重用!与nih综合症作斗争!;-)我不喜欢这个。a) 它不是普通的b)它坏了。以目前的形式来看,这不是一个好的整体解决方案/我修复了
返回
我忘记了。我还将其修改为泛型,并将其从dict子类化改为包含dict,我认为这确实更好。更通用。和
def
而不是
class
。。。oi,我必须回家了。我认为如果你重新研究你的答案,只指向一个现有的
代理
实现,而不是在这个实现上重新发明轮子,那会更好:)--但是代理模式是IHMO中另一个很好的解决方案。请随意证明我错了,但是对于这么简单的代理,任何一个软件包都可能过于复杂,而任何其他解决方案都只是一个配方,这与我这里介绍的差不多
f.tower
Out[127]: 1

f.floor
Out[128]: 2

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