返回自己的自定义OrderedDict

时间:2015-12-16 01:32:35

标签: python dictionary

我有以下自定义类:

Tuple

当我有多个键时,这个类完全符合我的要求,但是我没有做我想要的单键。

让我演示我的代码输出的内容:

array = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
print (array)
rows=4
cols=4
objects = [[0 for x in range(cols)]for y in range(rows)]
print (objects)



import random
player = "player"
row=random.randrange(0,3)
col=random.randrange(0,3)
if (objects[row][col]) == 0:
objects[row][col]= player




import random
goblin = "goblin"
flag = True
while (flag):
row=random.randrange(0,3)
col=random.randrange(0,3)
if (objects[row][col]) == 0:
    objects[row][col]= goblin
    flag = False

pit = "pit"
flag = True
while (flag):
row=random.randrange(0,3)
col=random.randrange(0,3)
if (objects[row][col]) == 0:
    objects[row][col]= pit
    flag = False

pit = "pit"
flag = True
while (flag):
row=random.randrange(0,3)
col=random.randrange(0,3)
if (objects[row][col]) == 0:
    objects[row][col]= pit
    flag = False


gold = "gold"
flag = True
while (flag):
row=random.randrange(0,3)
col=random.randrange(0,3)
if (objects[row][col]) == 0:
    objects[row][col]= gold
    flag = False
    print (objects)

objects[0][0]=1
objects[0][1]=2
objects[0][2]=3
objects[0][3]=4
objects[1][0]=5
objects[1][1]=6
objects[1][2]=7
objects[1][3]=8
objects[2][0]=9
objects[2][1]=10
objects[2][2]=11
objects[2][3]=12
objects[3][0]=13
objects[3][1]=14
objects[3][2]=15
objects[3][3]=16

print ("Welcome to the Adventure Game")
print ("You are in Room " , objects[player])

但是:

class MyArray (OrderedDict):
    def __init__ (self,*args):
        OrderedDict.__init__(self,*args)
    def __getitem__ (self, key):
        if not hasattr (key, '__iter__'):
            return OrderedDict.__getitem__ (self,key)
        return MyArray((k,self[k]) for k in key)

我希望它是:

x = MyArray()

x[0] = 3
x[1] = 4
x[2] = 5

print x[1,0,2]

MyArray([(1,4),(0,3),(2,5)])

这是我尝试修复它以我想要的方式行动(导致无限递归):

print x[1]

4

2 个答案:

答案 0 :(得分:5)

这里的关键是要意识到self[k]self.__getitem__(k)相同,所以你不想在self[k]内使用__getitem__,除非你实际上在尝试做一些递归。而是始终使用OrderedDict.__getitem__ (self,key)

在一个不相关的说明中,您通常不希望创建一个只调用父类的相同方法的方法,即:

class MyArray (OrderedDict):
    def __init__ (self,*args):
        OrderedDict.__init__(self,*args)

只需删除方法,python就会为你调用父类方法,继承很棒:)。

更新

经过一番挖掘后,我发现当您尝试打印MyArray时会发现无限递归,因为OrderedDict.__repr__调用OrderDict.items然后调用OrderDict.__getitem__(以self[key]的形式{1}}),然后它会在每个项目上调用__repr__ ...这里的问题是您正在修改__getitem__以执行与在Parent类中执行的操作非常不同的操作。如果您希望此类具有python类的完整功能,则需要覆盖在方法中任何位置使用self[key]的每个方法。您可以从items开始,例如:

def items(self):
    'od.items() -> list of (key, value) pairs in od'
    return [(key, OrderedDict.__getitem__(self, key)) for key in self]

当你遇到这种情况时,最好放弃子类并让OrderedDict成为新类的属性,例如:

class MyArray(object):

    def __init__(self, *args):
        self.data = OrderedDict(*args)

    def __getitem__(self, key):
        if not hasattr (key, '__iter__'):
            return MyArray([(key, self.data[key])])
        return MyArray([(k, self.data[k]) for k in key])

答案 1 :(得分:0)

Bi Rico 指出,self.items()中发生了无限递归。 这是一个有效的代码(基本上覆盖了self.items())

class MyArray (OrderedDict):
    def __getitem__ (self, key):
        if not hasattr (key, '__iter__'):
            return MyArray({key:OrderedDict.__getitem__ (self,key)})
        return MyArray((k,OrderedDict.__getitem__ (self,k)) for k in key)
    def items(self):
        '''
        called when the dictionary is printed
        '''
        return [(k, OrderedDict.__getitem__(self, k)) for k in self]

如果我从dict而不是OrderedDict继承,上面的代码可以在没有项目定义的情况下工作。