2010-02-16 99 views
1

我不明白x和y如何是同一個列表。我一直在嘗試使用print語句進行調試和import code; code.interact(local=locals())落入不同點,但我想不出到底是什麼在:-(會這些名單爲什麼相同?

from collections import namedtuple, OrderedDict 

coordinates_2d=["x","y"] 

def virtual_container(virtual_container, objects_type): 
    """Used to create a virtual object given a the type of container and what it holds. 
    The object_type needs to only have normal values.""" 
    if issubclass(virtual_container, list): 
     class my_virtual_container_class: 
      """This singleton class represents the container""" 
      def __init__(self): 
       #Define the default values 
       __vals__=OrderedDict([(key,list()) for key in objects_type]) 
       print(id(__vals__["x"]), id(__vals__["y"]))#ids are different: 12911896 12911968 
       #Then functions to access them 
       d={key: lambda self: self.__vals__[key] for key in objects_type} 
       d["__vals__"]=__vals__ 
       #Construct a named tuple from this 
       self.attr=type('attr_cl',(), d)() 
       print(id(self.attr.x()), id(self.attr.y()))#ids are same: 32904544 32904544 
      #TODO: Define the operators __del__, setitem, getitem. Also append 
     return my_virtual_container_class() 

#Nice method of handling coordinates 
coordinates=virtual_container(list, coordinates_2d) 
x=coordinates.attr.x() 
y=coordinates.attr.y() 
x.append(1) 
y.append(2) 
print(x, y)#Prints [1, 2] [1, 2] 
+0

我覺得這和這裏是一樣的問題:http://stackoverflow.com/questions/1867068/python-reference-problem – Ikke

+0

爲什麼不是'OrderedDict'的子類? –

+0

這是與名稱綁定相同的問題在這裏:http://stackoverflow.com/questions/139819/why-results-of-map-and-list-comprehension-are-different – jfs

回答

7

問題是這一行:

d={key: lambda self: self.__vals__[key] for key in objects_type} 

拉姆達使用變量的價值,但是這個值在lambda被調用的時候已經改變 - 所以所有的lambda實際上都會使用相同的值作爲key。

這個問題可以用一個小竅門:通過密鑰作爲默認參數值的拉姆達:

... lambda self, key=key: self.__vals__[key] ... 

這可以確保的key值被綁定到一個它在當時拉姆達被創建。

+0

哇,lambda可以有默認值嗎?我從來不知道! – Casebash

+0

-1:完全替換lambda遠遠好於修復它。在這個類中,不清楚爲什麼鍵值查找必須首先是lambda。事實上,目前還不清楚爲什麼這不僅僅是OrderedDict的一個子類。 –

0

我認爲有以下行應該是這(只可惜我不能測試,因爲我沒有Python 3中提供):

# Then functions to access them 
d = dict((key, lambda self: self.__vals__[key]) for key in objects_type) 
+0

Python增加了字典解析功能,所以我不需要使用字典功能 – Casebash