我有以下自定义类:
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
答案 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继承,上面的代码可以在没有项目定义的情况下工作。