《流畅的Python》是一本不可多得的好书,然而不知是有意或出于无意,作者在书中留下了一些陷阱,让我们从全书的第一个例子说起。
下面是本书第一个例子的源码:
import collections
Card=collections.namedtuple('Card',['rank','suit'])
class FrenchDeck:
ranks=[str(n) for n in range(2,11)] + list('JQKA') #1
suits='spades diamonds clubs hearts'.split() #2
def __init__(self):
self._cards=[Card(rank,suit) for suit in self.suits
for rank in self.ranks] #3
def __len__(self):
return len(self._cards)
def __getitem__(self,position):
return self._cards[position]
整个例子短小紧凑,但是仔细端详,会发现#1和#2两句声明的是两个类变量,而#3句却是用实例变量的方式来引用之。
从Python默认的行为看,这种情况是允许的。就是说,如果在方法中引用了某个没有定义的实例变量,那么会去查找同名的类变量,如果找到,则会获取同名类变量的值,否则引发异常。不信,你把ranks和suits两个类变量删掉试试,再次创建FrenchDeck类的对象,Python马上给你脸色看。