《流畅的Python》第一个例子中的陷阱

《流畅的Python》书中首个例子中,作者使用了类变量和实例变量的方式,可能导致混淆。当在方法中引用未定义的实例变量时,Python会查找并使用同名类变量。为保持语义清晰,应明确使用类变量。通过在__init__()方法中输出self.suits和self.ranks的id值,可以验证它们是类变量,所有对象共享。如果将suits和ranks改为实例变量,每个对象将拥有独立的内存空间。当类和实例变量同名时,实例变量会屏蔽类变量,要引用类变量需通过类名前缀。
摘要由CSDN通过智能技术生成

《流畅的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马上给你脸色看。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kingdragonfly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值