Python学习之路(六):基础知识之函数

1.函数语法

函数是对功能的封装

语法:def 函数名()

函数体

函数名() =--->调用函数

2.返回值

(1) 如果无函数体,不写return,没有返回值

(2) 如果在函数体中间或这末写return,返回的是None

  (3) 在函数中写 return 值,返回一个值,多个返回值接受到的是元组

3.参数

函数执行的时候给函数传递信息

  • 形参:函数声明的位置的变量
  • 实参:函数调用的时候的具体的值
  • 传参:把实参交给形参的过程

3.1 实参

1)位置参数

 

1 def chi(good_food, no_good_food, drink, ice_cream)
2     print(good_food, no_good_food, drink, ice_cream)
3 chi('法国鹅肝', '飞龙大辣片', '大白梨', '哈根达斯')

按照形参的参数位置给形参传参,当参数很多时,需要记住参数的位置

2)关键字参数

 

1 def chi(good_food, no_good_food, drink, ice_cream)
2     print(good_food, no_good_food, drink, ice_cream)
3 chi(drink="神仙水", ice_cream="老彬棍", good_food="盖浇饭", no_good_food="大烂片")

根据形参的参数名给形参传参

3)混合参数

前两者混合使用

 

1 def chi(good_food, no_good_food, drink, ice_cream)
2     print(good_food, no_good_food, drink, ice_cream)
3 chi('法国鹅肝', '飞龙大辣片', drink="神仙水", ice_cream="老彬棍")

在运用是必须先写位置参数,后写关键字参数,否则关键字参数会占位置参数的位置

(2) 形参

1) 位置参数

2) 默认参数

 

1 def regist(name, phone, gender='')  # 在变量声明的时候给定实参,默认值参数必须在参数列表的末尾
2     print(name,phone,gender)
3 regist('Shiledon', '1010011010')
4 regist('Richil', '5545', '')  # 不适用默认值时另给定实参

3)动态参数

*args

表示接收位置参数的动态传参,,接收到的数据类型是元组

1 def chi(*food):  #函数名是food,*表示动态传参
2     print(food)
3 chi('可乐', '馒头', '酱油')

各类参数的位置:位置参数==> *args ==> 默认值参数

1 def chi(name, *food, location='天津'):
2     print(name, *food, location)
3 chi('刘大哥', '玉米', '土豆')

**kwargs

关键字的动态传参:

1 def chi(**food):
2     print(food)
3 chi(good_good='盖浇饭', no_good_food='卫龙', drink='可口可乐')

顺序:位置参数==> *args ==> 默认值参数 ==> **kwargs

4.文档注释

文档注释也可以称为函数注释:

 

 1 def func(a, b):
 2     """
 3     这一行用来解释这个函数的功能
 4     :param a: 第一个参数值
 5     :param b:第二个参数值
 6     :return:返回值
 7     """
 8     return a+b
 9 
10 print(func(1, 4))
11 print(func.__doc__)
12 print(str.__doc__)  #可以看其他类型数据的文档注释

 

5.聚合和打散

1 def func(*food):  #这里是将所有的food参数聚合到一个元组中
2     print(food)
3 lst = ['煎饼果子', '来一套', '美滋滋']
4 func(*lst)  # 这个时候是将传参列表中的元素打散,方便传参,可以打散list,tuple,dic,set
1 def func(**food):
2     print(food)
3 dic = {"good_food":"煎饼果子", "no_good_food":"辣条"}
4 func(**dic)  #字典打散成关键字参数

6.函数名

 

1.函数名也可以当作变量名进行使用

 1 def func_1():
 2     print('我是1')
 3 def func_2():
 4     print('我是2')
 5 
 6 def func_3():
 7     print('我是3')
 8 
 9 lst = [func_1, func_2, func_3]
10 for el in lst:
11     el()

2.函数名可以作为参数传递给函数

 1 def my():
 2     print('我是my')
 3 def proxy(fn):  # proxy代理
 4     print('在处理之前')
 5     fn()
 6     print('在处理之后')
 7 
 8 proxy(my)
 9 
10 # 结果:在处理之前
11 #       我是my
12 #       在处理之后

3.函数可以作为返回值

1 def func():
2     print('我是func')
3     a = 10
4     def inner():
5         print('我是inner')
6     return inner  # 返回函数inner的内存地址
7 print(func())

如果要执行inner():

1 def func():
2     print('我是func')
3     a = 10
4     def inner():
5         print('我是inner')
6     return inner  # 返回函数inner的内存地址
7 ret = func()
8 ret()

7.名称空间

在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了, 至于函数内部的变量和逻辑, 解释器是不关心的. 也就是说一开始的时候函数只是加载进来, 仅此而已, 只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕, 这些函数内部变量占用的空间也会随着函数执行完毕而被清空。

命名空间分类:

​ 1. 全局名称空间—> 我们直接在py文件中, 函数外声明的变量都属于全局名称空间

​ 2. 局部名称空间—> 在函数中声明的变量会放在局部名称空间

​ 3. 内置名称空间—> 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置名称空间  

 

 

 1 全局名称空间
 2 a = 10  # 全局名称空间中的内容
 3 def func():  # func()也在全局名称空间中 ==> 顶格
 4     b = 10  # b为局部变量
 5     return a*b
 6 def func_1():
 7     print(a)
 8 print(func())
 9 func_1()
10 python的命名空间:内置变量==> 全局变量 ==> 局部变量(函数调用的时候产生)

 

1 a = 10
2 def fn():
3     b = 20
4     def gn():
5         pass
6         print(globals())
7         print(locals())
8     gn()  # 局部的函数要在内部进行调用
9 fn()

global

1 a = 10
2 def fn():
3     global a  # global可以将全局中的内容引入到函数内部
4     a = 20
5 fn()
6 print(a)
1 a = 10
2 def fn():
3     global a  # global可以将全局中的内容引入到函数内部
4     
5     a += 10  # 此时局部没有变量a,会将全局的a引入到局部,先进行a+10然后赋值
6     #  给a,但是a是全局变量,不能修改,所以程序不能执行,所以应该加入global
7 fn()
8 print(a)

nonlocal

1 def outer():
2     a = 10
3     def inner():
4         nonlocal a  # 寻找外层函数离它最近的变量
5         a = 20
6     inner()
7     print(a)
8 outer()

8.闭包

 

闭包:在内层函数中访问外层函数的变量

 

1 def outer():
2     a = 10
3     def inner():
4         print(a)
5     inner()
6 outer()

 

闭包的作用:

1.可以保护变量不受侵害

1 def outer():
2     a = 10  # 函数内部的变量a对于外界是不开放的
3     def inner():
4         nonlocal a
5         a = 20
6         print(a)
7     inner()

2.可以让一个变量常驻内存

1 def outer():
2     a = 10  # 常驻内存,为了inner执行的时候有值
3     def inner():
4         print(a)
5     return inner
6 fn = outer()
7 fn()

可以用closure查看是否闭包:

1 def func():
2     a = 10
3     def inner():
4         print(a)
5     print(inner.__closure__)  # 如果打印的是None,则不是闭包
6 
7 func()

 9.匿名函数

 匿名函数是函数的一种简略表达,语法为:

lambda 参数: 返回值

 1 # 一般的函数:
 2 def func(n):
 3     return n * n
 4 
 5 ret = func(9)
 6 print(ret)
 7 
 8 # 匿名函数:
 9 
10 a = lambda n : n*n
11 ret = a(9)
12 print(ret)

匿名函数举例:

1 suiyi = lambda x, y : (x, y)
2 print(suiyi(1, 3))

匿名函数还可以进行动态传参:

1 fn = lambda *args: max(args)
2 
3 print(fn(1, 2, 7, 9, 22))

 10.函数的递归调用

 函数的递归调用是指在函数体内调用函数本身:

 

 1 # 这是一个函数递归调用的例子,可以用来测试递归深度,官方指出最大1000次递归
 2 count = 1
 3 def func():
 4     global count
 5     print('111', count)  
 6 
 7 
 8     count = count + 1
 9     func()
10 func()

 

posted on 2020-02-23 15:06  Py_studying  阅读(181)  评论(0编辑  收藏  举报

导航