[python]一个关于默认参数的老问题和一个有关优化的新问题
一个老问题:
def func(defau=[]):
defau.append(1)
return defau print(func())#print[1]
print(func())#print[1,1]
print(func())#print[1,1,1]
学python时候应该都遇到过这个问题,为什么?一般的说法是把这个可变的默认参数和函数绑定在一块了
但是,怎么绑定的???
看python文档[1],里面对def的解释:
A function definition is an executable statement. Its execution binds the function name in the current local namespace to a function object .
一个可执行的声明,在现有的名称空间中把函数名字和函数对象绑定在一块了。
也就是说,这种绑定只有在def声明执行的时候才会发生,只有在def语句执行的时候,才会把函数名字和一个新的函数对象绑定在一块[2]。
那么,这些和默认参数有什么关系?
这默认参数的关系就是,只有当这种绑定发生的时候,默认参数才会得到赋值,换句话说,只有在def声明执行的时候,默认参数所引用的对象才会和函数对象结合起来。
所以,在上面的例子中,因为def语句只执行了一次,所以几次调用函数func其实都是执行的同一个函数对象,使用的同一个list:
def func(defau=[]):
defau.append(1)
return defau print(id(func()))#print 1756350390856
print(id(func()))#print 1756350390856
print(id(func()))#print 1756350390856
看大神laike9m的博客[3]的时候,发现其实可以利用这一点对python的性能进行优化的。
我们都知道,python中名称的查找顺序为LEGB,也就是local->enclosing->global->builtin,如果我们把一个全局变量赋值给一个函数的默认参数,把一个全局变量变为一个函数的局部变量,那么在查找链中,就不用进行到global,直接在local域中就可以得到需要的变量了:
import timeit
setup1="""
import math
def cal():
math.sin(1)+math.cos(1)
"""
setup2="""
import math
def cal2(sin=math.sin,cos=math.cos):
sin(1)+cos(1)
"""
t1=timeit.Timer(setup1,"print('setup1')")
t2=timeit.Timer(setup2,"print('setup2')")
print(t1.timeit(100))
print(t2.timeit(100))
#setup1
#0.0003371067712671346
#setup2
#8.921092541729796e-05
可以看到,在执行100遍的情况下,运行时间相差一个量级
参考资料:[1]python 文档
[2]Default parameter values in python
[python]一个关于默认参数的老问题和一个有关优化的新问题的更多相关文章
- Python中的默认参数(转)
add by zhj: Python设计者为何将默认参数设计成这样呢?参见Python函数参数默认值的陷阱和原理深究 原文:https://github.com/acmerfight/insight_ ...
- Python进阶-函数默认参数
Python进阶-函数默认参数 写在前面 如非特别说明,下文均基于Python3 一.默认参数 python为了简化函数的调用,提供了默认参数机制: def pow(x, n = 2): r = 1 ...
- python中的默认参数
https://eastlakeside.gitbooks.io/interpy-zh/content/Mutation/ 看下面的代码 def add_to(num, target=[]): tar ...
- C/C++ Python的函数默认参数
发现C/C++ Python的函数可以使用默认参数,来减少传参时候的参数个数. 但是:这样的默认参数最好是不变对象! #include <stdio.h> #include <st ...
- Python函数的默认参数的设计【原创】
在Python教程里,针对默认参数,给了一个“重要警告”的例子: def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print( ...
- 在python函数中默认参数的一些坑
一.默认参数 python为了简化函数的调用,提供了默认参数机制: 这样在调用pow函数时,就可以省略最后一个参数不写: 在定义有默认参数的函数时,需要注意以下: 必选参数必须在前面,默认参数在后: ...
- Python之定义默认参数
定义函数的时候,还可以有默认参数. 例如Python自带的 int() 函数,其实就有两个参数,我们既可以传一个参数,又可以传两个参数: >>> int('123') 123 > ...
- python里的默认参数
def extendList(val, test=[]): test.append(val) return test list1 = extendList(10) list2 = extendList ...
- 经典面试题-python函数之默认参数
1.可变的默认参数----list 示例: def add(a, mylist=[]): # print(id(mylist)) mylist.append(a) return mylist pri ...
随机推荐
- BZOJ第一页刷题计划
BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...
- 51nod 小Z的trie(Trie+广义SAM)
[题目链接] http://www.51nod.com/contest/problem.html#!problemId=1647 [题意] 给定一个n个字符串的Trie,每次询问一个字符串在Trie上 ...
- IIS 问题集锦
本文主要记录IIS中遇到的各种问题以及注意事项 一.在IIS中.NET Framework的版本选择为什么没有v3.0,v3.5? 首先需要澄清的是这里有两个关于版本的东西:ASP.NET和.NET ...
- 查看sql语句加锁信息
问题: 最近使用quartz集群,总是报deadlock问题,所以需要查看一下执行的sql导致的加锁冲突. 步骤: 1.在要测试的库中创建指定表innodb_lock_monitor create t ...
- linux文件管理 -> 系统文件属性
-rw-------. 1 root root 4434 May 30 13:58 ks.cfg -rw-------. ①:文件类型与权限 ②:硬链接次数 root ③:所属用户 root ④:所属 ...
- js中图片获取src的正则
链接: JavaScript 正则表达式:http://www.runoob.com/js/js-regexp.html js正则匹配出所有图片及图片地址src的方法:http://www.jb51. ...
- MAVLink v1.0详解——结构
本文针对 MAVLink v1.0版本,协议版本:3. MAVLink是为微型飞行器MAV(Micro Air Vehicle)设计的(LGPL)开源的通讯协议.是无人飞行器和地面站(Ground C ...
- MongoDB安全:内置角色概览
官文列举如下(文档不长,过英语四级者可以轻松阅读,就不需要看本文额)(基于MongoDB 3.6的文档,4.0也没有变化): Role-Based Access Control Built-In Ro ...
- Python基础(1):dir(),help()
Python:3.6.4 开始编写Python程序了...可是,某个模块怎么用呢?模块里的函数怎么用呢?...使用本文介绍的dir().help()两个帮助函数可以 获得绝大部分开发所需要的信息! d ...
- NLP里面好的学习资料
别人推荐的网址: http://ruder.io/deep-learning-nlp-best-practices/index.html#wordembeddings