2013-05-03 12 views
2

我正在使用貨架來存儲一些數據。Shelve:無法泡菜<class'method'>:屬性查找builtins.method失敗

Traceback (most recent call last): 
    File "rogue.py", line 312, in <module> 
    curses.wrapper(game) 
File "/usr/lib/python3.3/curses/__init__.py", line 94, in wrapper 
    return func(stdscr, *args, **kwds) 
File "rogue.py", line 289, in game 
    save_game(y,x) 
File "rogue.py", line 119, in save_game 
    file['player'] = player 
File "/usr/lib/python3.3/shelve.py", line 124, in __setitem__ 
    p.dump(value) 

_pickle.PicklingError: Can't pickle <class 'method'>: attribute lookup builtins.method failed 

我環顧四周,發現有關未綁定方法的東西可能會導致這種情況,但我在我的代碼中找不到問題。

問題出現在

file['player'] = player 

球員是實體類:

player = entity(y,x, '@', 200, False) 

這是實體類代碼:

class entity: 
def __init__(self, y, x, ch, speed, ai=True): 
    self.y = y 
    self.x = x 
    self.ch = ch 
    self.speed = speed 
    self.ai = ai 


    self.ap = 0 
    self.current_action = {'action': self.wait, 'cost': self.speed} 
    self.my_turn = False 

def draw(self): 
    world[self.y][self.x].walkable = False 
    gamepad.addch(self.y, self.x, self.ch) 

def take_turn(self): 

    self.my_turn = True 
    cost = self.current_action['cost'] 
    self.current_action['action']() 

    return cost 
def move(self, dy, dx): 

    if self.my_turn == False: 
     self.current_action = {'action': partial(self.move, dy,dx), 'cost':200} 
     deck.append(self) 

    if self.my_turn == True: 

     #p = previous 
     py = self.y 
     px = self.x 


     pt = world[py][px] 
     #Paint previous ground tile 
     pt.walkable = True 
     gamepad.addch(pt.y,pt.x,pt.ch) 

     if world[dy][dx].walkable == True: 
      self.y = dy 
      self.x = dx 
      world[dy][dx].walkable = False 

     if self.ai == False: 
      draw_map(self.y,self.x) 


     self.my_turn = False 
    return self.y,self.x 

def wait(self): 
    self.current_action = {'action': self.wait, 'cost': self.speed} 
def drunk_move(self): 
    dy = self.y + random.randint(-1,1) 
    dx = self.x + random.randint(-1,1) 
    self.move(dy, dx) 
def ai_simple(self): 

    #Figure out if player is higher or not: 
    wherey = self.y - player.y 
    if wherey > 0: 
     dy = self.y-1 
    else: 
     dy = self.y+1 

    wherex = self.x - player.x 
    if wherex > 0: 
     dx = self.x-1 
    else: 
     dx = self.x+1 

    self.move(dy, dx) 

發佈這個我試過之前用pudb做最後的一面 - 而我' M還對

file['world'] = world 

得到一個錯誤_

│ File "/usr/lib/python3.3/shelve.py", line 124, in     │ 
│__setitem__               │ 
│ p.dump(value)              │   
│_pickle.PicklingError: Can't pickle <class        │ 
│'__main__.tile'>: attribute lookup __main__.tile failed    │ 

(其中不 pudb運行代碼時不顯示)

這是世界:

world = [[ tile(yy,xx,True,'.') 
    for xx in range(WORLD_WIDTH) ] 
     for yy in range(WORLD_HEIGHT) ] 

這是類瓷磚:

class tile: 
def __init__(self,y,x,walkable,ch): 
    self.x = x 
    self.y = y 
    self.walkable = walkable 
    self.ch = ch 

最後,這是調用貨架完整的功能:

def save_game(): 
    file = shelve.open('savegame', 'n') 
    file['world'] = world 
    file['player']= player 

    file.close() 

我相信這是所有相關的代碼。

什麼原因導致這些錯誤?

回答

1

的第一個問題是這條線在你的實體類原因造成的:

self.current_action = {'action': self.wait, 'cost': self.speed} 

current_action包含綁定方法,不能醃引用。您可以使用__getstate____setstate__確實改變酸洗行爲,所以在酸洗時不要使用該方法,而是使用名稱(或在分配了partial對象的情況下的名稱和參數),並在取消時刻恢復該值。

我不確定你的第二個問題,但是如果它只發生在調試器中運行它時,它可能是一個問題,如何debuger加載__main__模塊。您可以嘗試將您的__main__塊移到另一個模塊中,並從那裏導入並放置您的代碼。有時候可以解決這些問題。

相關問題