python函数默认参数为可变对象的理解
1.代码在执行的过程中,遇到函数定义,初始化函数生成存储函数名,默认参数初识值,函数地址的函数对象。
2.代码执行不在初始化函数,而是直接执行函数体。
代码实例
这要从函数的特性说起,在 Python 中,函数是第一类对象(function is the first class object),换而言之,函数也是对象,跟整数、字符串一样可以赋值给变量、当做参数传递、还可以作为返回值。函数也有自己的属性,比如函数的名字、函数的默认参数列表。
# 函数的名字
>>> func.__name__
'func'
# 函数的默认参数列表
>>> func.__defaults__
([ 1, 1, 1, 1, 1], 1)
def是一条可执行语句,Python 解释器执行 def 语句时,就会在内存中就创建了一个函数对象(此时,函数里面的代码逻辑并不会执行,因为还没调用嘛),在全局命名空间,有一个函数名(变量叫 func)会指向该函数对象,记住,至始至终,不管该函数调用多少次,函数对象只有一个,就是function object,不会因为调用多次而出现多个函数对象。

函数对象生成之后,它的属性:名字和默认参数列表都将初始化完成。

初始化完成时,属性 __default__ 中的第一个默认参数 numbers 指向一个空列表。
当函数第一次被调用时,就是第一次执行 func()时,开始执行函数里面的逻辑代码(此时函数不再需要初始化了),代码逻辑就是往numbers中添加一个值为1的元素

第二次调用 func(),继续往numbers中添加一个元素

第三次、四次依此类推。
所以现在你应该明白为什么调用同一个函数,返回值确每次都不一样了吧。因为他们共享的是同一个列表(numbers)对象,只是每调用一次就往该列表中增加了一个元素
如果我们显示地指定 numbers 参数,结果截然不同。
>>> func(numbers=[ 10, 11])
[ 10, 11, 1]

因为numbers被重新赋值了,它不再指向原来初始化时的那个列表了,而是指向了我们传递过去的那个新列表对象,因此返回值变成了 [10, 11, 1]
那么我们应该如何避免前面那种情况发生呢?就是不要用可变对象作为参数的默认值。
正确方式:
>>> deffunc(numbers=None, num=1):
... ifnumbers isNone:
... numbers = [num]
... else:
... numbers.append(num)
... returnnumbers
...
python函数默认参数为可变对象的理解的更多相关文章
- 【转】Python函数默认参数陷阱
[转]Python函数默认参数陷阱 阅读目录 可变对象与不可变对象 函数默认参数陷阱 默认参数原理 避免 修饰器方法 扩展 参考 请看如下一段程序: def extend_list(v, li=[]) ...
- Python面试题目之Python函数默认参数陷阱
请看如下一段程序: def extend_list(v, li=[]): li.append(v) return li list1 = extend_list(10) list2 = extend_l ...
- [python]函数默认参数顺序问题
python 函数参数定义有四类: 1.必选参数:调用函数时候必须赋值的参数. a,须以正确的顺序传入函数b,调用时的数量必须和声明时的一样 def exa(x): return x #b作为参数进入 ...
- 使用可变对象作为python函数默认参数引发的问题
写python的都知道,python函数或者方法可以使用默认参数,比如 1 def foo(arg=None): 2 print(arg) 3 4 foo() 5 6 foo("hello ...
- python函数默认参数陷阱
对于学习python的人都有这样的困惑 def foo(a=[]): a.append(5) return a Python新手希望这个函数总是返回一个只包含一个元素的列表:[5].结果却非常不同,而 ...
- python函数默认参数作用域
当def函数参数默认值为对象时,例如列表[],字典{} 示例1:猜测一下,会输出什么??? def ddd(a,b=[]): b.append(a) return b print(ddd(1)) pr ...
- Python 函数(默认参数)
默认参数 设置默认参数时,有两点需要注意:一是必选参数在前,默认参数在后,否则python的解释器会报错二是当函数有多个参数时,把变化大的参数放前面,变化小的放后面,变化小的参数就可以作为默认参数 d ...
- Python函数默认参数的陷阱
默认参数实际上只有一个值 代码1 def func(l = 1): l += 1 print(l) func() func() func() 代码2 lst = [] def func(a,l = l ...
- python函数默认参数坑
def add(a=3,b): print a,b add(4) 这样写的话,运行的话就会报错:SyntaxError: non-default argument follows default ar ...
随机推荐
- Holedox Eating HDU - 4302 2012多校C 二分查找+树状数组/线段树优化
题意 一个长度$n<=1e5$的数轴,$m<=1e5$个操作 有两种一些操作 $0$ $x$ 在$x$放一个食物 $1$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...
- 006_tcpdump专题
抓包是排查问题非常重要的一种方式,这里汇总常用的排查日常问题的,tcpdump在linux机器上的使用姿势. 一.排查statsd打点情况. 线上出现statsd打点的指标无法正常显示的情况,需要排查 ...
- Python-Numpy数组计算
一.NumPy:数组计算 1.NumPy是高性能科学计算和数据分析的基础包.它是pandas等其他各种工具的基础.2.NumPy的主要功能: ndarray,一个多维数组结构,高效且节省空间 无需循环 ...
- restful中的分页
普通分页 普通分页类似于Django中的分页 源码 class PageNumberPagination(BasePagination): """ A simple pa ...
- 通过设置ie的通过跨域访问数据源,来访问本地服务
1.首先设置通过域访问数据源 设置通过域访问数据源 2.javascript脚本ajax使用本地服务登录(评价,人证的类似)接口 <html> <head> <scrip ...
- linux_OEL5.4_安装Oracle11g中文教程图解
一.安装ORACLE10g 软件(11.2.0.0) 参考pdf:链接:http://pan.baidu.com/s/1pLHU94J 密码:keo8 (一)安装前的包支持 1. 虚拟机yum 环境搭 ...
- Flask框架(一)
Flask框架 Flask本身想当于一个内核,其自身几乎所有功能都依靠扩展(邮件扩展Flask-Mail.用户认证Flask-Login),都需要用第三方的扩展来实现.其WSGI工具箱采用Werkze ...
- vue.js 入门学习
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- windows下如何安装pip以及如何查看pip是否已经安装成功
最近刚学习python,发现很多关于安装以及查看pip是否安装成的例子都比较老,不太适合于现在(python 3.6 )因此,下一个入门级别的教程. 0:首先如何安装python我就不做介绍了. 1: ...
- css之操作属性
1.文本 1.文本颜色:color 颜色属性被用来设置文字的颜色. 颜色是通过CSS最经常的指定: 十六进制值 - 如: #FF0000 一个RGB值 - 如: RGB(255,0,0) 颜色的名称 ...