1. 不要使用可变类型作为参数的默认值

摘自《流畅的Python》8.4.1

class HauntedBus:
"""备受幽灵乘客折磨的校车"""
def __init__(self, passengers=[]):
self.passengers = passengers def pick(self, name):
self.passengers.append(name) def drop(self, name):
self.passengers.remove(name)

运行测试用例

>>> bus1 = HauntedBus(['Alice', 'Bill'])
>>> bus1.passengers
['Alice', 'Bill']
>>> bus1.pick('Charlie')
>>> bus1.drop('Alice')
>>> bus1.passengers
['Bill', 'Charlie']
>>> bus2 = HauntedBus()
>>> bus2.pick('Carrie')
>>> bus2.passengers
['Carrie']
>>> bus3 = HauntedBus()
>>> bus3.passengers
['Carrie']
>>> bus3.pick('Dave')
>>> bus2.passengers
['Carrie', 'Dave']
>>> bus2.passengers is bus3.passengers
True
>>> bus1.passengers
['Bill', 'Charlie']

问题来了:登上 bus3 的 Dave 出现在 bus2 中。

原因在于,bus2.passengers 和 bus3.passengers 指代同一个列表。即没有指定初始乘客的 HauntedBus 实例会共享同一个乘客列表。

出现这个问题的根源是,默认值在定义函数时计算(通常在加载模块时),因此默认值变成了函数对象的属性。因此,如果默认值是可变对象,而且修改了它的值,那么后续的函数调用都会受到影响。

可以通过 __defaults__ 属性中的那些幽灵学生:

>>> dir(HauntedBus.__init__)  # doctest: +ELLIPSIS
['__annotations__', '__call__', ..., '__defaults__', ...]
>>> HauntedBus.__init__.__defaults__
(['Carrie', 'Dave'],)

可变默认值导致的这个问题说明了为什么通常使用 None 作为接收可变值的参数的默认

值。

Python惯用法的更多相关文章

  1. Python高级用法总结

    Python很棒,它有很多高级用法值得细细思索,学习使用.本文将根据日常使用,总结介绍Python的一组高级特性,包括:列表推导式.迭代器和生成器.装饰器. 列表推导(list comprehensi ...

  2. python argparse用法总结

    转:python argparse用法总结 1. argparse介绍 argparse是python的一个命令行解析包,非常适合用来编写可读性非常好的程序. 2. 基本用法 prog.py是我在li ...

  3. Anaconda下载及安装及查看安装的Python库用法

    Anaconda下载及安装及查看安装的Python库用法 Anaconda 是一个用于科学计算的 Python 发行版,提供了包管理与环境管理的功能.Anaconda 利用 conda 来进行 pac ...

  4. python enumerate用法总结【转】

    enumerate()说明 enumerate()是python的内置函数 enumerate在字典上是枚举.列举的意思 对于一个可迭代的(iterable)/可遍历的对象(如列表.字符串),enum ...

  5. Python高级用法

    Python高级用法 三元表达式 x = 10 y = 20 print(x if x > y else y) x = 100 y = 20 print(x if x > y else y ...

  6. RAII惯用法:C++资源管理的利器(转)

    RAII惯用法:C++资源管理的利器 RAII是指C++语言中的一个惯用法(idiom),它是“Resource Acquisition Is Initialization”的首字母缩写.中文可将其翻 ...

  7. Python import用法以及与from...import的区别

    Python import用法以及与from...import的区别 在python用import或者from...import来导入相应的模块.模块其实就是一些函数和类的集合文件,它能实现一些相应的 ...

  8. 做个地道的c++程序猿:copy and swap惯用法

    如果你对外语感兴趣,那肯定听过"idiom"这个词.牛津词典对于它的解释叫惯用语,再精简一些可以叫"成语".想要掌握一门语言,其中的"成语" ...

  9. Erase-Remove 惯用法

    看到<Effective STL>条款 9 的时候想到了我以前复习的"如何正确使用迭代器删除元素",我面试时使用的也是里面的方法,看面试官的反应好像也没有什么问题,还问 ...

随机推荐

  1. MySQL执行外部sql脚本文件命令是报错:unknown command

    使用source导入外部sql文件: mysql> source F:\php\bookorama.sql; -------------- source F: -------------- ER ...

  2. Pyqt5_QPushButton

    QPushButton 状态 isDown() 提示按钮是否已按下 isChecked() 提示按钮是否已经标记 isEnable() 提示按钮是否可以被用户点击 isCheckAble() 提示按钮 ...

  3. 简说Spring中的资源加载

    声明: 本文若有 任何纰漏.错误,请不吝指正!谢谢! 问题描述 遇到一个关于资源加载的问题,因此简单的记录一下,对Spring资源加载也做一个记录. 问题起因是使用了@PropertySource来进 ...

  4. 百度前端技术学院2018笔记 之 利用 CSS animation 制作一个炫酷的 Slider

    前言 题目地址 利用 CSS animation 制作一个炫酷的 Slider 思路整理 首先页面包含三种东西 一个是type为radio的input其实就是单选框 二是每个单选框对应的label 三 ...

  5. 全网首发,腾讯T3-3整理Netty学习方案(体系图+项目+学习文档)

    前言: 想要学好一门技术,最起码要对他有一定的了解,起码听说过相应的底层原理的东西吧,最起码你要有一点能和别人交流的内容吧,下面是我精简的一点内容,希望对于大家了解netty能有一点帮助 Netty是 ...

  6. Thunar左侧边栏不完全显示PLACES的解决

    场景 我的笔记本装上系统时用的英文,安装中文之后,发现文件管理器的默认的几个文件夹 Desktop.Music.Videos.Downloads等都变成了中文,由于是新安装的系统,就重新生成 loca ...

  7. mysql页面查询

    <?php $link = mysql_connect('127.0.0.1', 'root', 'root'); if (!$link) { die('Could not connect: ' ...

  8. [JavaWeb基础] 005.Hibernate的配置和简单使用

    1.Hibernate简介 Hibernate是一个基于Java的开源的持久化中间件,对JDBC做了轻量的封装.采用ORM映射机制,负责实现Java对象和关系数据库之间的映射,把sql语句传给数据库, ...

  9. parrot os的一些坑

    burpsuite 破解版的运行环境需要jdk8,jdk11无法运行 选择jdk环境 update-alternatives --config java 截图工具 sudo apt install f ...

  10. PAT1065 单身狗 (25分) 思路记录——参考大神柳婼

    1065 单身狗 (25分)   “单身狗”是中文对于单身人士的一种爱称.本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱. 输入格式: 输入第一行给出一个正整数 N(≤ 50 000), ...