如何改变一个实例的dict()的行为 [英] How to change behavior of dict() for an instance

查看:160
本文介绍了如何改变一个实例的dict()的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在写一个扩展一个字典的类,它现在使用一个方法dictify将其转换成一个dict。我想要做的是改变它,以便在对象上调用dict()导致相同的行为,但我不知道要覆盖哪个方法。这是不可能的,还是我缺少一些完全明显的东西? (是的,我知道下面的代码不起作用,但我希望它可以说明我正在做什么。)

  from collections import defaultdict 

class RecursiveDict(defaultdict):
'''
一个递归默认的dict。

>>> a = RecursiveDict()
>>>> a [1] [2] [3] = 4
>>>> a.dictify()
{1:{2:{3:4}}}
'''
def __init __(self):
super(RecursiveDict,self) __init __(RecursiveDict)

def dictify(self):
'''获取树中项目的标准字典'''
return dict([(k, (v.dictify()if isinstance(v,dict)else v))
for(k,v)in self.items()])

def __dict __(self):
'''获取树中项目的标准字典''
print [(k,v)for(k,v)in self.items()]
return dict ()(b)()()()()()()()()

编辑:更清楚地显示问题:

 >>> b = RecursiveDict()
>>> b [1] [2] [3] = 4
>>> b
defaultdict(< class'__main __。RecursiveDict'>,{1:defaultdict(< class'__main __。RecursiveDict'>,{2:defaultdict(< class'__main __。RecursiveDict' {3:4})})})
>>> dict(b)
{1:defaultdict(< class'__main __。RecursiveDict'>,{2:defaultdict(< class'__main __。RecursiveDict'> {3:4})})}
>>>> b.dictify()
{1:{2:{3:4}}}

我想要dict(b)与b.dictify()相同b

解决方案

你的方法没有什么问题,但这是类似于Perl的Autovivification功能,它已经在Python中实现了这个问题。

  class RecursiveDict(dict):
执行perl的自动修复功能。 $$ b $ _ $($)
try:
return dict .__ getitem __(self,item)
除了KeyError:
value = self [item ] = type(self)()
返回值

>>> a = RecursiveDict()
>>>> a [1] [2] [3] = 4
>>>> dict(a)
{1:{2:{3:4}}}

编辑



根据@Rosh Oxymoron的建议,使用 __缺少__ 导致更简洁实现。需要Python> = 2.5

  class RecursiveDict(dict):
执行perl的自动修复功能
def __missing __(self,key):
value = self [key] = type(self)()
返回值


So I'm writing a class that extends a dictionary which right now uses a method "dictify" to transform itself into a dict. What I would like to do instead though is change it so that calling dict() on the object results in the same behavior, but I don't know which method to override. Is this not possible, or I am I missing something totally obvious? (And yes, I know the code below doesn't work but I hope it illustrates what I'm trying to do.)

from collections import defaultdict

class RecursiveDict(defaultdict):
    '''
    A recursive default dict.

    >>> a = RecursiveDict()
    >>> a[1][2][3] = 4
    >>> a.dictify()
    {1: {2: {3: 4}}}
    '''
    def __init__(self):
        super(RecursiveDict, self).__init__(RecursiveDict)

    def dictify(self):
        '''Get a standard dictionary of the items in the tree.'''
        return dict([(k, (v.dictify() if isinstance(v, dict) else v))
                     for (k, v) in self.items()])

    def __dict__(self):
        '''Get a standard dictionary of the items in the tree.'''
        print [(k, v) for (k, v) in self.items()]
        return dict([(k, (dict(v) if isinstance(v, dict) else v))
                     for (k, v) in self.items()])

EDIT: To show the problem more clearly:

>>> b = RecursiveDict()
>>> b[1][2][3] = 4
>>> b
defaultdict(<class '__main__.RecursiveDict'>, {1: defaultdict(<class '__main__.RecursiveDict'>, {2: defaultdict(<class '__main__.RecursiveDict'>, {3: 4})})})
>>> dict(b)
{1: defaultdict(<class '__main__.RecursiveDict'>, {2: defaultdict(<class '__main__.RecursiveDict'>, {3: 4})})}
>>> b.dictify()
{1: {2: {3: 4}}}

I want dict(b) to be same as b.dictify()

解决方案

Nothing wrong with your approach, but this is similar to the Autovivification feature of Perl, which has been implemented in Python in this question. Props to @nosklo for this.

class RecursiveDict(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

>>> a = RecursiveDict()
>>> a[1][2][3] = 4
>>> dict(a)
{1: {2: {3: 4}}}

EDIT

As suggested by @Rosh Oxymoron, using __missing__ results in a more concise implementation. Requires Python >= 2.5

class RecursiveDict(dict):
    """Implementation of perl's autovivification feature."""
    def __missing__(self, key):
        value = self[key] = type(self)()
        return value

这篇关于如何改变一个实例的dict()的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆