热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python函数进阶_Python函数进阶

一、函数什么是函数?类似一个封装体,它是组织好的,可重复使用的,实现相关功能的代码段函数的特性有:减少重复代码;

一、函数

什么是函数?

类似一个封装体,它是组织好的,可重复使用的,实现相关功能的代码段

函数的特性有:减少重复代码;使程序变的可拓展;使程序变的易维护

二、定义函数

语法:

def 函数名(参数1,参数2,参数3,...): #函数名要见名思意

'''注释'''

函数体

return 返回的值

三、函数的调用

1.调用函数

格式:函数名()

def star():

print("you are beautiful girl")

star()

2.函数返回值

函数在执行过程中只要遇到return语句,就会停止执行并返回结果

如果未在函数中指定return,那这个函数的返回值为None

什么时候函数需要返回值,什么时候函数不需要返回值?

通常有参函数需要有返回值,通常无参函数不需要有返回值

四、函数的参数

形参

1.位置参数必须传值

1 def func(a, b):2 the_max = a if a > b elseb #三元运算3 returnthe_max4 res = func(3, 5)5 print(res)

2.默认参数(不传值就会显示默认的值)

1 def people(name, sex="男"):2 print(name,sex)3 people("xfxing")4 people("alex", "gay")

实参

1.按位置传值

2.按关键字传参

3.混合传参 关键字参数永远在位置参数之后

defmy_sum(x, y):return x +y

num1= my_sum(10, 20) #位置参数

num2 = my_sum(x=20, y=99) #关键字传参

num3 = my_sum(1, y=88) #1--位置参数,y=88--关键字参数

print(num1, num2,num3)

动态传参

动态参数也叫非固定参数,需要传的参数个数不定,可用“args”,“kwargs”接收

1.agrs是元组的形式,接收除去键值对以外的所有参数。

2.kwargs接受的只是键值对的参数,并保存在字典中。

如果不确定要传的参数,最好使用非固定参数(万能参数)

def stu_register(name, age, *args, **kwargs):print(name, age, args, kwargs)

stu_register("alex", 22)

stu_register("Boy", 21, "linux", "python")

stu_register("washington", 22, "linux", "java", "python", sex="男", province="JiangXi")

五、嵌套函数

name = "御姐" #外层定义的变量

defwrapper():

name= "小可爱" #外层函数定义的变量

definner():

name= "萝莉" #内层函数定义的变量

print(name)

inner()print(name)

wrapper()print(name)

View Code

六、匿名函数(lambda函数)

就是不需要显示的指定函数名

func=lambda x,y:x*y if x

print(func(8, 16))

foo= lambda x, y: x**yprint(foo(2, 3))

优点:1. 节省代码量

2. 看着高级

七、递归

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

def calc(n): #1 程序执行过程

v = int(n/2) #3 7 11 15

print(v) #4 8 12 16

if v > 0: #5 9 13 17

calc(v) #6 10 14

print(n) #18 19 20 21

calc(10) #2

递归特性:

1.必须有一个明确的结束条件

2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

二分查找

八、内置函数

如何查看Python中全部内置变量和内置函数?

1.>>>dir(__builtins__)

2.>>>import builtins

>>>dir(builtins)

九、名称空间

1.什么是名称空间

名称到对象的映射。命名空间是一个字典的实现,键为变量名,值是变量对应的值。各个命名空间是独立的,一个命名空间中不能有重名,不同的命名空间可以重名。

2.名称空间分类

全局命名空间:global

局部命名空间:local

外部嵌套的命名空间:enclosing

内置命名空间:built-in

3.名称空间的加载顺序

内置命名空间(程序运行前加载)-->全局命名空间(程序运行中:从上到下加载)-->局部命名空间(程序运行中:调用时才加载)

4.名称空间的取值顺序:

在局部调用:局部命名空间-->全局命名空间-->内置命名空间 L->E->G->B

LEGB(local->enclosing function->global->built-in)

在全局调用:全局命名空间-->内置命名空间 G->B

十、作用域

1.什么是作用域

作用域是针对变量而言,指申明的变量在程序里的可应用范围。或者称为变量的可见性。

2.作用域分类

全局作用域:范围最大,在整个文件的任意位置都能被引用,全局有效

局部作用域:局部名称空间,只能在局部范围内生效

3.查看作用域的值

locals()和globals(),提供了基于字典的访问局部和全局变量的方式:

locals():函数会以字典类型返回当前位置的全部局部变量。

globals():函数会以字典类型返回当前位置的全部全局变量。

4.关键字(global与nonlocal)

global关键字作用:

声明一个全局变量

在局部作用域想要对全局作用域的全局变量进行调用,可用global(仅适用于字符串、数字)

对可变数据类型(list,dict,set)可以直接引用,不用通过global

a = 1

deffunc():global a #声明为全局变量

a = 5

print(a)

func()print(a) #结果:5 5

nonlocal作用:

不能修改一个全局变量

在局部作用域中,对外层(非全局作用域)的变量进行引用和修改,引用到了哪一层,那层以下这个变量全部发生改变

defwrapper():

foo= 19

defouter():

foo= 23

print(foo)definner():

nonlocal foo

foo= foo + 29

print(foo)

inner()print(foo)

outer()print(foo)

wrapper()#输出结果: 23 52 52 19

十一、函数的本质

1.函数可以被当成值或变量引用

1 deffunc():2 return

3

4

5 print(func)6 f = func #将其传给变量f

7 print(f)

2.函数可以被当成容器类型的元素存储

deffunc1():print('func1')deffunc2():print('func2')deffunc3():print('func3')

lists=[func1, func2, func3]

lists[0]()

lists[1]()

lists[2]()

3.可以当做函数的参数和返回值

def func(): #1 程序执行过程

print("func") #5 8

def func1(args1): #2

args1() #4

return args1 #6 func作为返回值

f= func1(func) #3 func作为参数

f() #7

十二、闭包

在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包(即:内层函数,对外层函数(非全局)的变量的引用)。

deffunc():

name= 'alice'

definner():print(name)returninner

f=func()

f()

1.检测闭包函数的公共属性:closure

如果里层的函数调用__closure__方法输出是一个cell对象,则证明是闭包。

defwrapper():

name= 'alice'

definner():print(name) #调用外层函数的变量

inner()print(inner.__closure__)

wrapper()#输出结果是:#alice#(,)

2.带有参数的闭包函数

def wrapper(a): #a是外部传入的参数

b = 10

definner(a):print(a +b)return a +b

inner(a)

wrapper(10)

十三、装饰器

本质上就是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。

无参的装饰器

import time #1 程序执行流程

def timmer(func): #2

def wrapper(*args, **kwargs): #4

start_time = time.time() #7

res = func(*args, **kwargs) #my_max(1,2) #8

stop_time = time.time() #12

print('run time is %s' % (stop_time-start_time)) #13

return res #14

return wrapper #5

@timmer#3

defmy_max(x, y):print('my_max function') #9

res = x if x > y else y #10

return res #11

res= my_max(1, 2) #res=wrapper(1,2) #6

print('=====>', res) #15

带参数的装饰器

十四、迭代器

1.可迭代对象

可以直接作用于for循环的对象统称为可迭代对象,即Iterable。

常见迭代对象:

集合数据类型(str list tuple dict set range)

generator,包括生成器和带yield的generator function。

2.判断可迭代对象的方法

1)dir(对象)

str1 = 'hello' #字符串为可迭代对象

print('__iter__' indir(str1))#输出结果:

True

2)isinstance()方法

使用isinstance()判断一个对象是否是Iterable对象

>>> from collections importIterable>>>isinstance([], Iterable)

True>>>isinstance({}, Iterable)

True>>> isinstance('abc', Iterable)

True>>> isinstance((x for x in range(10)), Iterable)

True>>> isinstance(100, Iterable)

False

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections importIterator>>> isinstance((x for x in range(10)), Iterator)

True>>>isinstance([], Iterator)

False>>>isinstance({}, Iterator)

False>>> isinstance('abc', Iterator)

False

3.可迭代对象转换迭代器

可迭代对象执行obj.iter()得到的结果就是迭代器对象。

而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象。

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

把list、dict、str等Iterable变成Iterator可以使用iter()函数:

>>>isinstance(iter([]), Iterator)

True>>> isinstance(iter('abc'), Iterator)

True

为什么list、dict、str等数据类型不是Iterator?

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

4.迭代器的优缺点

优点:提供一种统一的、不依赖于索引的迭代方式;惰性计算、节省内存

缺点:无法获取长度(只有在next完毕才知道有几个值);一次性的,只能往后走,不能往前退

十五、生成器

把列表解析的[]换成()得到的就是生成器表达式

>>> L = [x*x for x in range(10)]>>>L

[0,1, 4, 9, 16, 25, 36, 49, 64, 81]>>> g =(x*x for x in range(10))>>>g at 0x0000028604E21048>

>>>next(g)

0>>>next(g)1

>>>next(g)4

>>>next(g)9

>>>next(g)16

>>>next(g)25

>>>next(g)36

>>>next(g)49

>>>next(g)64

>>>next(g)81

>>>next(g)

Traceback (most recent call last):

File"", line 1, in StopIteration

每次调用next()函数获得generator的下一个返回值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

可用for循环迭代,不需要每次调用next(),同时也不会出现StopIteration的错误。

1 g = (x * x for x in range(10))2 for n ing:3 print(n)

比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:1, 1, 2, 3, 5, 8, 13, 21, 34, ...

deffib(max):

n, a, b= 0, 0, 1

while n

a, b= b, a +b

n= n + 1

return 'done'

#a, b = b, a + b相当于 t = (b, a + b) # t是一个tuple#a = t[0]#b = t[1]

输出结果:

>>> fib(6)1

1

2

3

5

8

'done'

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

deffib(max1):

n, a, b= 0, 0, 1

while n

a,b= b, a +b

n= n + 1

return 'done'

for n in fib(6):print(n)

generator和函数的执行流程不一样!函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

函数改成generator后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代。

用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

1 g = fib(6)2 whileTrue:3 try:4 x =next(g)5 print('g:', x)6 exceptStopIteration as e:7 print('Generator return value:', e.value)8 break

输出结果:

g: 1

g: 1

g: 2

g: 3

g: 5

g: 8

Generator return value: done

列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存。



推荐阅读
  • 本文介绍了Python对Excel文件的读取方法,包括模块的安装和使用。通过安装xlrd、xlwt、xlutils、pyExcelerator等模块,可以实现对Excel文件的读取和处理。具体的读取方法包括打开excel文件、抓取所有sheet的名称、定位到指定的表单等。本文提供了两种定位表单的方式,并给出了相应的代码示例。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 树莓派Linux基础(一):查看文件系统的命令行操作
    本文介绍了在树莓派上通过SSH服务使用命令行查看文件系统的操作,包括cd命令用于变更目录、pwd命令用于显示当前目录位置、ls命令用于显示文件和目录列表。详细讲解了这些命令的使用方法和注意事项。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
author-avatar
gl君
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有