在这里,我们将给大家分享关于python中函数的准确计时的知识,同时也会涉及到如何更有效地19-3-14Python中函数的进阶、Python中函数参数的详细介绍(附实例)、python中函数如何定义
在这里,我们将给大家分享关于python中函数的准确计时的知识,同时也会涉及到如何更有效地19-3-14Python中函数的进阶、Python中函数参数的详细介绍(附实例)、python中函数如何定义?python函数的调用方法介绍、python中函数如何达到C++中带有引用参数的效果的内容。
本文目录一览:- python中函数的准确计时
- 19-3-14Python中函数的进阶
- Python中函数参数的详细介绍(附实例)
- python中函数如何定义?python函数的调用方法介绍
- python中函数如何达到C++中带有引用参数的效果
python中函数的准确计时
我正在Windows上的python中进行编程,想准确地测量函数运行所花费的时间。我已经编写了一个函数“
time_it”,该函数需要另一个函数,然后运行它并返回运行时间。
def time_it(f, *args): start = time.clock() f(*args) return (time.clock() - start)*1000
我称其为1000次并取平均值。(最后的1000常数以毫秒为单位给出答案。)
该函数似乎可以正常工作,但是我有一种na不安的感觉,那就是我做错了什么,通过这种方式,我花的时间比函数运行时实际花费的时间更多。
有没有更标准或可接受的方式来做到这一点?
当我将测试函数更改为调用打印以使其花费更长的时间时,time_it函数返回的平均时间为2.5毫秒,而cProfile.run(’f()’)返回的平均时间为7.0毫秒。我认为我的函数会高估时间(如果有的话),这是怎么回事?
另外要注意的是,我关心的是功能彼此之间的相对时间,而不是绝对时间,因为绝对时间显然取决于硬件和其他因素。
答案1
小编典典建议您不要签出内置的Python分析器(profile
或cProfile
根据您的需要),而不是编写自己的分析代码:http
:
//docs.python.org/library/profile.html
19-3-14Python中函数的进阶
1.动态参数:
def func(*args): #在形参位置*叫做聚合
print(args) #元组形式
func(1,2,3,4,5,6)
def func(**kwargs): # 动态关键字参数
print(kwargs)
func(a=1, b=2, c=3) # 关键字的形式传参
*args 和 **kwargs
是可以更换的,但是程序员约定都用它
用途:在不明确接收参数、数量时使用*args和**kwargs
位置参数>动态的位置参数
形参:位置>动态位置>默认参数>动态默认参数
实参:位置>关键字参数
在实参调用的时候,*将可迭代的对象打散,字典是将键取出
在形参出现*就是在聚合
在实参调用的时候,**将字典打散成 关键字参数(键=值)
在形参处出现**就是将关键字参数聚合成一个字典。
注意:参数arg、*args、**kwargs三个参数的位置必须是一定的。必须是(arg,*args,**kwargs)这个顺序,否则程序会报错。
2.函数的注释
print(aaa._doc_)查看注释
3.名称空间
1. 内置空间中所有代码——内置空间
2. 自己写的py文件——全局空间
3. 函数中的代码——局部空间
*注:
加载顺序:
内置空间——>全局空间——>局部空间
查找值的顺序:
局部空间——>全局空间——>内置空间——>报错
作用域:
全局作用域 内置+全局=全局作用域
局部作用域 函数内的就是局部作用域
a = 10
def func():
global a #global:声明a为全局变量。//找到要修改的值,修改后放回
a += 1
func()
print(a)
4.函数的嵌套
第一种函数嵌套:函数嵌套函数
第二种函数嵌套:多个函数嵌套
5.global nonlocal
nonlocal:在一个局部空间内,nonlocal会修改离他最近的那个变量,如果上一层没有就继续向上找,直到走到局部空间头部,都没有则报错。
global:在局部修改全部变量,如果没有就创建一个新的。
def func(*args): #在形参位置*叫做聚合
print(args) #元组形式
func(1,2,3,4,5,6)
def func(**kwargs): # 动态关键字参数
print(kwargs)
func(a=1, b=2, c=3) # 关键字的形式传参
Python中函数参数的详细介绍(附实例)
本篇文章给大家带来的内容是关于
Python的函数定义比较简单,借助于关键字def进行实现,但是参数的灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数、关键字参数、命名关键字参数以及参数组合,这使得函数定义出来的接口,不仅能处理复杂的参数,还能简化调用者的代码
一、位置参数
在函数定义的时候,指定参数的位置顺序。位置参数必须在被调用函数定义中的准确顺序来进行传递。
例如:计算x的n次方
def powern(x,n): s = 1 while n >0: s = s * x n = n -1 return s
x与n这两个参数都是位置参数。调用函数时,必须传入且传入的两个值按照位置顺序依次赋给参数x和n,若缺省,则会报错。例如:
立即学习“Python免费学习笔记(深入)”;
>>> powern(5) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: powern() missing 1 required positional argument: ''n''</module></stdin>
二、默认参数
在函数定义中,为参数预先定义默认值。当在函数调用时,若没有为参数提供指定值,则使用默认值。
例如:仍旧是求x的n次方,但是默认为x的3次方。
def powern( x,n = 3): s = 1 while n >0: s = s * x n = n -1 return s
执行:powern(2),相当于调用powern(2,3)
如果要求2的四次方,则需要执行:powern(2,4)
设置默认参数的好处?
默认参数可以简化函数的调用,降低调用函数的难度。无论是简单调用还是复杂调用,函数只需定义一个。
例如上述powern()的例子,当传入n的其他值时,则可以实现x的其他n次方。
但是在使用默认参数的时候,如果使用不当,也会有坑。先来了解一下可变参数和不可变参数作为函数参数时的不同:
不可变参数作为函数参数
>>> a = 1 >>> def func(a): ... print(''func_id:'',id(a)) ... a = 2 ... print(''after_func_id:'',id(a),''id(2):'',id(2)) ... >>> print(''out_of_func_id:'',id(a),''id(1):'',id(1)) out_of_func_id: 501962480 id(1): 501962480 # 全局变量a的id >>> func(a) # 将全局参数a传入函数 func_id: 501962480 # a=1 的id after_func_id: 501962496 id(2): 501962496 >>> print(a) # 退出函数,a的值仍为1 1
当把全局a传递给函数后,函数自动复制一份引用。执行完a=2之后,id(a)的内存地址发生变化。但是跟外层的a没有关系。
可变对象作为函数参数
>>> a = [] >>> def func2(a): ... print(''func2_id:'',id(a)) ... a.append(1) ... >>> print(''out_of_func2_id'',id(a)) out_of_func2_id 59694296 >>> func2(a) func2_id: 59694296 >>> print(a) [1]
变量a的类型为list,是可变对象。函数的引用指向的是可变对象,地址没有发生变化,所以函数操作后,a的内容发生了改变。
所以当再次操作func2(a)函数时,产生跟预期不一样的结果:
>>> func2(a) func2_id: 59694296 # a地址不变 >>> print(a) [1, 1] # 因为第一次执行func2(a)时,已经修改了a=[1],再次调用时,在[1]里新增
例如:
def add_end( L=[] ): # 设置为一个list变量L(对象可变) L.append(''end'') return L >>> add_end( ) [''end''] >>> add_end() [''end'', ''end'']
当连续重复使用默认参数调用时,结果出现错误。
Python函数在定义的时候,默认参数L的值就被计算出来了,即[]。L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
可以改为:
def add_end( L=None ): # L为不变对象 if L is None: L = [] L.append(''end'') return L
则无论调用多少次,都不会出现问题。
所以,定义默认参数要牢记一点:默认参数必须指向不变对象!因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁。
设置默认参数时,有几点需要注意
一.必选参数在前,默认参数在后,否则Python的解释器会报错。
二.如何设置默认参数?当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
三.不要使用可变对象作为默认参数。
三、可变参数*args
可变参数,即传入的参数个数是可变的,0至任意个。
因为参数个数不确定,则可以使用一个list 或者tuple传进来。之后在函数调用时会自动组装为一个tuple。
例如:
def calc(numbers): # 变量 sum = 0 for n in numbers: sum = sum + n * n return sum >>> calc( [1,2,3] ) # 传入的是一个list 14
利用可变参数 *args:
def calc( *numbers ): sum = 0 for n in numbers: # 在函数内部,numbers组装成一个tuple sum = sum + n * n return sum >>> calc( ) # 0个参数 0 >>> calc( 1,3,5,7 ) # 多个参数 84 >>> num = [1,2,3] # list >>> calc( *num ) # *list –> tuple 14 >>> t = (1,3,5) >>> calc( t ) # tuple(错误) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in calc TypeError: can''t multiply sequence by non-int of type ''tuple'' >>> calc( *t ) 35</stdin></module></stdin>
函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数。
四、关键字参数**kw
关键字参数**kw允许传入0个至任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。例如:
def person(name , age , **kw ): print(''name:'',name,''age:'',age,''other:'',kw) >>> person(''xiong'',18) name: xiong age: 18 other: {} >>> person(''xiong'',18,city = ''SH'') # city是原本没有的参数,但是因为有**kw name: xiong age: 18 other: {''city'': ''SH''}
关键参数有什么用?可以扩展函数的功能。比如在person()函数里面,可以保证接收到name和age这两个参数。但是如果提供更多参数,也能收到。当然也可以先组装一个dict,再把该dict转换为关键字参数传递进去:
>>> extra ={''city'':''shanghai'',''job'':''SET''} # dict的定义 >>> person(''xiong'',18,city = extra[''city''],job=extra[''job'']) # dict的使用 name: xiong age: 18 other: {''city'': ''shanghai'', ''job'': ''SET''} # dict的内容 >>> person(''xiong'',18,**extra) name: xiong age: 18 other: {''city'': ''shanghai'', ''job'': ''SET''}
【总结】**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
五、命名关键字参数
如果要限制关键字参数的名字,就可以用命名关键字参数。需要一个特殊分隔符“”,“”后面的参数被视为命名关键字参数。如果缺少“*”,Python解释器则无法识别位置参数和命名关键字参数。在调用时,必须指定参数名字与参数值。
例如,只接收city和job作为关键字参数,可以使用如下定义:
def person( name ,age,*,city,job): print(name , age , city , job ) >>> person(''xiong'', 18, city=''shanghai'', job=''tester'') xiong 18 shanghai tester
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
>>> def person( name,age,*args,city,job ): # 此处city和job也是命名关键字参数 ... print(name, age, city, job)
命名关键字参数必须传入参数名,如果没有传入参数名,调用将会报错:
>>> person(''xlp'',18,''shanghai'',''tester'') # 错误调用 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: person() missing 2 required keyword-only arguments: ''city'' and ''job'' >>> person(''xlp'',18,city=''shanghai'',job=''tester'') # 正确调用 xlp 18 shanghai tester</module></stdin>
命名关键字参数可以有缺省值,从而简化调用:
>>> def person1(name,age,*,city=''shanghai'',job): ... print(name,age,city,job) ... >>> person1(''xlp'',18,job=''engineer'') xlp 18 shanghai engineer
六、参数组合
在Python中定义函数,可以用位置参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。
但是要注意,参数定义的顺序必须是:位置参数、默认参数、可变参数、命名关键字参数和关键字参数。
【总结】
(1)定义可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个list、tuple;
**kw是关键字参数,kw接收的是一个dict;
(2)调用函数时如何传入可变参数和关键字参数的语法:
可变参数直接传入:func(1,2,3)
可变参数间接传入:先组装成list或tuple,l=(1,2,3),再通过args传入,func(l)
关键字参数直接传入:func(a=1,b=2)
关键字参数间接传入:先组装成dict,d={‘a’:1,’b’:2},再通过kw传入,func(d)
(3)命名关键字参数 是为了限制调用者可以传入的参数名,同时可以提供默认值。
(4)定义命名的关键字参数在没有可变参数的情况下,不要忘记写分隔符*,否则定义的将是位置参数
相关推荐:
Python中函数的可变参数
理解Python中函数的参数
以上就是Python中函数参数的详细介绍(附实例)的详细内容,更多请关注php中文网其它相关文章!
python中函数如何定义?python函数的调用方法介绍
本篇文章给大家带来的内容是关于python中函数如何定义?python函数的调用方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
1. 函数的概念,函数是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集
2. 函数的作用,使用函数可以加强代码的复用性,提高程序编写的效率
3. 函数的使用,函数必须先创建才可以使用,该过程称为函数定义,函数创建后可以使用,使用过程称为函数调用
函数定义与调用:
立即学习“Python免费学习笔记(深入)”;
1) >>> def 函数名(形参1,形参2): # 定义
... 函数体
函数名(实参1,实参2) #调用
4. 函数的注释,写在函数定义的下方,使用”””内容”””的方法在pycharm函数的调用的地方鼠标放上按Ctrl可以快速查看函数的注释内容
5. 函数参数的作用域,函数内部定义的叫做局部变量,函数外部的变量叫做全局变量,局部变量的作用域只限于函数内部使用
>>> def test(a, b): ... print(a, b) ... >>> test(1, 2) 1 2 >>> print(a) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined
形参是外部是无法被调用的
6. 函数外部的变量在函数内部可以直接调用但是无法修改全局变量的内容,可以在函数内部使用global 变量名重新定义后修改
1) >>> a = 1 >>> def test(b): ... print(b) ... print(a) ... >>> test(2) 2 1
可以直接调用外部定义的变量
2) >>> a = 1 >>> def test(): ... a += 1 ... print(a) ... >>> test() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in test UnboundLocalError: local variable 'a' referenced before assignment
函数内部本来是无法修改函数外部的变量的值
3)>>> a = 1 >>> def test(): ... global a ... a += 1 ... print(a) ... >>> test()
在函数内部重新声明了变量a之后就可以修改变量a的值了
7. 函数的返回值,python中函数的关键字return, 生成迭代器 yield 返回
1) 定义格式:
def 函数名():
函数体
return 返回值
2) 调用格式:
变量名 = 函数名()
3) return 语句执行后面的内容将不再执行
以上就是python中函数如何定义?python函数的调用方法介绍的详细内容,更多请关注php中文网其它相关文章!
python中函数如何达到C++中带有引用参数的效果
比如我写了一个python的小代码:
x = 1 y = 2 def swap(x,y): x,y = y,x print "(x:%d and y:%d)" % (x,y) swap(x,y) print "(x:%d and y:%d)" % (x,y)程序输出:
>>> (x:2 and y:1) (x:1 and y:2)但是我希望swap函数能够改变x,y变量,像C++中传递引用swap(&x, &y)一样。如何办到呢?
PS:问题的根源是我在编写python代码的时候,总是通过返回结果来达到引用的效果,但是发现这样写很麻烦,如果能有C++引用的效果,就好了。
关于python中函数的准确计时的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于19-3-14Python中函数的进阶、Python中函数参数的详细介绍(附实例)、python中函数如何定义?python函数的调用方法介绍、python中函数如何达到C++中带有引用参数的效果的相关信息,请在本站寻找。
本文标签: