Python惯用法
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惯用法的更多相关文章
- Python高级用法总结
Python很棒,它有很多高级用法值得细细思索,学习使用.本文将根据日常使用,总结介绍Python的一组高级特性,包括:列表推导式.迭代器和生成器.装饰器. 列表推导(list comprehensi ...
- python argparse用法总结
转:python argparse用法总结 1. argparse介绍 argparse是python的一个命令行解析包,非常适合用来编写可读性非常好的程序. 2. 基本用法 prog.py是我在li ...
- Anaconda下载及安装及查看安装的Python库用法
Anaconda下载及安装及查看安装的Python库用法 Anaconda 是一个用于科学计算的 Python 发行版,提供了包管理与环境管理的功能.Anaconda 利用 conda 来进行 pac ...
- python enumerate用法总结【转】
enumerate()说明 enumerate()是python的内置函数 enumerate在字典上是枚举.列举的意思 对于一个可迭代的(iterable)/可遍历的对象(如列表.字符串),enum ...
- Python高级用法
Python高级用法 三元表达式 x = 10 y = 20 print(x if x > y else y) x = 100 y = 20 print(x if x > y else y ...
- RAII惯用法:C++资源管理的利器(转)
RAII惯用法:C++资源管理的利器 RAII是指C++语言中的一个惯用法(idiom),它是“Resource Acquisition Is Initialization”的首字母缩写.中文可将其翻 ...
- Python import用法以及与from...import的区别
Python import用法以及与from...import的区别 在python用import或者from...import来导入相应的模块.模块其实就是一些函数和类的集合文件,它能实现一些相应的 ...
- 做个地道的c++程序猿:copy and swap惯用法
如果你对外语感兴趣,那肯定听过"idiom"这个词.牛津词典对于它的解释叫惯用语,再精简一些可以叫"成语".想要掌握一门语言,其中的"成语" ...
- Erase-Remove 惯用法
看到<Effective STL>条款 9 的时候想到了我以前复习的"如何正确使用迭代器删除元素",我面试时使用的也是里面的方法,看面试官的反应好像也没有什么问题,还问 ...
随机推荐
- 解惑求助-关于NetCore2.2中间件响应的问题
背景介绍:基于netcore2.2开发api接口程序,自定义了一个异常捕获中间件,用于捕获未经处理的异常以及状态码404.500等访问(设计的出发点就是,出现了非200的响应,我这边全部会进行处理成2 ...
- ABAP基础1:概念
包(Package)也称作开发类,是为了将程序等对象根据功能划分,进行区分和管理而导入的概念 每一个开发对象,如程序.类,都要隶属一个包,包一般隶属于某一个模块 每个包拥有一个CTS号,CTS号用于系 ...
- eclipse的Android一些问题
我最近在学习Android 用eclipse来写Android项目 一开始就遇到了许多的坑——但好在有老师们帮助.还有百度: 现在我开始总结: 1.安装eclipse,这个暂时不说,因为我还没遇到什么 ...
- 【Java】手把手模拟CAS,瞬间理解CAS的机制
话不多少,先看个案例,[模拟100个用户,每个用户访问10次网站]”: public class ThreadDemo1 { //总访问量 ; //模拟访问的方法 public static void ...
- 一、CentOS6.8安装MySQL5.6
一.官网下载rpm安装包 https://dev.mysql.com/downloads/ 版本选中如图中红色框 二.卸载旧mysql 1.检查是否安装有mysql rpm -qa | grep -i ...
- 设计一个多功能的MyTime类 代码参考
#include <iostream> #include <cstdio> using namespace std; class MyTime { private: int h ...
- Keycloak快速上手指南,只需10分钟即可接入Spring Boot/Vue前后端分离应用实现SSO单点登录
登录及身份认证是现代web应用最基本的功能之一,对于企业内部的系统,多个系统往往希望有一套SSO服务对企业用户的登录及身份认证进行统一的管理,提升用户同时使用多个系统的体验,Keycloak正是为此种 ...
- Chisel3 - bind - PortBinding
https://mp.weixin.qq.com/s/NaInHsJgOwG03BLNF-wlxQ 介绍Module输入输出端口如何进行绑定. 1. IO() 在定义一个模块 ...
- Chisel3 - util - LFSR16
https://mp.weixin.qq.com/s/DSdb4tmRwDTOki7mbyuu9A 实现16位线性反馈移位寄存器.可用于生成简单的伪随机数. 参 ...
- Java实现蓝桥杯模拟递增的数
问题描述 一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,例如1135是一个数位递增的数,而1024不是一个数位递增的数. 给定正整数 n,请问在整数 1 至 n 中有多少个数 ...