1,函数的初识
函数:以功能(完成一件事)为导向。例如:登录,注册。一个函数就是一个功能
随调随用
优点:1,减少代码的重复性。2,增强代码可读性
# 函数式编程
s1 = 'cfgjsxdfgdzfjkghiasvhidfgb'
l1 = [1, 5, 5, 3, 8, 5, 5, 8, 9, 4, 4, 4]
def my_len(s):
count = 0
for i in s:
count += 1
return count
print(my_len(s1))
print(my_len(l1))
结构: def 关键字,定义函数。 meet 函数名:与变量设置相同,具有可描述性。 函数体:有缩进。
def meet():
print('打开tantan')
print('左滑一下')
print('右滑一下')
print('找人')
print('悄悄话')
print('约....走起')
return '妹子一枚', 132, [22, 33, 44]
ret = meet() # 将print里面的内容返回给ret
print(ret, type(ret)) # ('妹子一枚', 132, [22, 33, 44]) <class 'tuple'>
return:总结 1,在函数中,终止函数 2,return 可以给函数的执行者返回值 1,return单个值 单个值 2,return多个值 (多个值,)元组形式
2,函数的参数
形参
1,位置参数
def meet(sex, age, skill):
print('进行筛选:性别:{},年龄{},{}'.format(sex, age, skill))
meet('男', '25', 'python技术好的')
2,关键字参数
def meet(sex, age, skill, hight, weight):
print('进行筛选:性别:{},年龄{},{},身高是{},体重{}'.format(sex, age, skill, hight, weight))
meet('男', '25', 'python技术好的', 180, 60)
meet(sex='男', age='25', skill='python技术好的', hight=180, weight=60) # 关键字传参,必须一一对应,可以不按顺序
3,混合参数
def meet(sex, age, skill, hight, weight):
print('进行筛选:性别:{},年龄{},{},身高是{},体重{}'.format(sex, age, skill, hight, weight))
return '进行筛选:性别:{},年龄{}'.format(sex, age)
meet('男', '25', skill='python技术好的', hight=180, weight=60) # 既有位置参数,也有关键字参数 位置参数一定在关键字参数前面
# 进行筛选:性别:男,年龄25,python技术好的,身高是180,体重60 混合参数
4,默认值参数
def meet(age, skill, hight, weight, sex='女'): # sex='女',就是默认参数,写到最后面
print('进行筛选:性别:{},年龄{},{},身高是{},体重{}'.format(sex, age, skill, hight, weight))
return '进行筛选:性别:{},年龄{}'.format(sex, age)
meet('25', 'python技术好的', hight=180, weight=60, sex='男') # 还可以强制修改
实参
函数执行时使用的参数
def meet(sex): # 函数的定义:sex接受的参数形式参数
print('进行筛选:性别:{}'.format(sex))
meet('女') # '女'函数执行的参数:实际参数
3,函数的参数(2)
形参的角度
def eat(a, b, c, d):
print('我请你吃:{}\t{}\t{}\t{}'.format(a, b, c, d))
eat('鸡', '鸭', '鱼', '肉')
此时增加内容就需要修改源码
def eat(a, b, c, d, e, f):
print('我请你吃:{}\t{}\t{}\t{}'.format(a, b, c, d, e, f))
eat('鸡', '鸭', '鱼', '肉', '蛋', '蔬')
1,万能参数。*args
万能参数:*args,约定成俗的
*函数定义时:*代表聚合。将所有的位置参数聚合成一个元组,赋值给了args。
def eat(*args):
print('我请你吃:{}\t{}\t{}\t{}'.format(*args))
eat('鸡', '鸭', '鱼', '肉', '蛋', '蔬')
# 练习
# 写一个函数,计算你传入函数的所有的 数字的和
def add(*args):
sum1 = 0
for i in args:
sum1 += i
return sum1
s = add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(s)
2,万能参数 **kwargs
在函数的定义值时:**将所有的关键字参数聚合到一个字典,将这个字典赋值给了kwargs。
def func(**kwargs):
print(kwargs)
func(name='alex', age=19, sex='男')
万能参数:*args,**kwargs,
def func(*args, **kwargs):
print(args)
print(kwargs)
func('1,2,3,4', name='564')
3,参数的位置顺序
def func(a, b, *args, sex='男', c, **kwargs):
print(a, b)
print(sex)
print(args)
print(c)
print(kwargs)
func(1, 2, 3, 4, 5, 6, 7, sex='女', name='alex', age=18, c=666) # c 必须要关键字传参
形参角度的最终顺序:位置参数,*args,默认参数,仅限关键字参数,**kwargs
4,名称空间
三种名称空间
名称空间也是命名空间
prthon分为三个空间: 1,全局名称空间(当前py文件) 2,局部名称空间(函数,并且是存在于函数执行时) 3,内置名称空间(builtins.py)
全局名称空间: 就是记录的是整个文件中的变量与值的对应关系,以及函数名与函数体的对应关系的内存空间 随着代码的结束而消失
a = 1
b = 2
def func():
print(666)
c = 3
局部名称空间(临时名称空间): 就是记录函数体里的变量与值的对应关系 随着函数的结束而消失
a = 1
b = 2
def func():
f = 5 # 只能在函数体中使用
print(f)
c = 3
func()
内置名称空间: python源码给你提供的一些内置函数,如:print(),input()...
空间的加载顺序
内置名称空间 ----> 全局名称空间 ----> 局部名称空间(函数执行时)
取值顺序(就近原则) (单向不可逆只能是,局 --> 全 --> 内)
# 取值顺序(就近原则) (单向不可逆只能是,局 --> 全 --> 内)
name = 'alex' # 全局变量
def func():
name = '太白' # 局部变量
print(name)
func()
print(input) # <built-in function input> # 内置变量
作用域
两个作用域: 1,全局作用域: 内置名称空间 全局名称空间 2,局部作用域: 局部名称空间 局部作用域可以调用全局作用域
date = '周五'
def func():
# print(date)
return date
print(func()) # 周五
def func():
a = 10
print(a)
func()
print(a) # NameError: name 'a' is not defined,全局不能调用局部
# 只引用,不修改,例--两个count不是同一个count,因为存储地址不同
count = 1
def func():
count = 100
print(id(count))
func() # 140707257224560
print(id(count)) # 140707257221392
局部作用域不能改变全局作用域,当python解释器读取到局部作用域时,发现你对一个变量进行修改操作。 解释器会认为你在局部已经定义过这个局部变量了,他就从局部找这个局部变量,找不到报错
count = 100
def func():
# count += 1
print(id(count))
func()
print(id(count))
def func():
count = 1
def inner():
print(count)
inner()
func()
5,内置函数(题目,检测函数执行过程的掌握)
输出的顺序
# 例1
def func1():
print('in func1')
print(3)
def func2():
print('in func2')
print(4)
func1()
print(1)
func2()
print(2)
# 例2
def func1():
print('in func1')
print(3)
def func2():
print('in func2')
func1()
print(4)
print('===============')
print(1)
func2()
print(2)
# 例3
def fun2():
print(2)
def fun3():
print(6)
print(4)
fun3()
print(8)
print('===============')
print(3)
fun2()
print(5)
答案:例1:in func1,3,1,in func2,4,2
例2:1,in func2,in func1,3,4,2
例3:3,2,4,6,8,5
6,global,nonlocal
默认参数的陷阱
陷阱只针对与默认参数是可变的数据类型
# 例1
def func(name, sex='男'):
print(name)
print(sex)
func('alex')
# 例2
def func(name, alist=[]):
alist.append(name)
return alist
ret = func('alex')
print(ret, id(ret)) # ['alex'] 2996731269640
ret2 = func('太白金星')
print(ret2, id(ret2)) # ['alex', '太白金星'] 2996731269640
例子:
1,
def func(a, list=[]):
list.append(a)
return list
print(func(10)) # [10]
print(func(20, [])) # [20]
print(func(100)) # [10, 100]
上面的程序相当于:
执行一步打印一次 l1 = [] l1.append(10) print(l1) l2 = [] l2.append(20) print(l2) l1.append(100) print(l1)
2,
def func(a, list=[]):
list.append(a)
return list
ret1 = func(10, )
ret2 = func(20, [])
ret3 = func(100, )
print(ret1) # [10, 100]
print(ret2) # [20]
print(ret3) # [10, 100]
全部执行完再打印
局部作用域的坑
在函数中,如果定义一个变量,但是在定义这个变量之前引用了这个变量,那么解释器认为:语法错误
count = 1
def func():
count += 1
print(count)
func()
# 在函数中,如果定义一个变量,但是在定义这个变量之前引用了这个变量,那么解释器认为:语法错误
count = 1
def func():
print(count)
count = 3
func()
global nonlocal
global
1,在局部作用域中声明一个全局变量。
必须先调用函数,再输出被声明的局部变量
# 例子
name = 'alex'
def func():
name = '太白金星'
name1 = 'alex'
print(name, name1)
func() # 太白金星 alex
print(name1) # 报错
# 对比例子
def func():
global name1
name = '太白金星'
name1 = 'alex'
print(name, name1)
func() # 太白金星 alex
print(name1) # alex
# 必须先调用函数,再输出被声明的局部变量
2,修改全局变量
count = 1
def func():
global count
count += 2
print(count)
print(count) # 1
func() # 3
print(count) # 3
nonclocal
1,不能操作全局变量
# 例1
count = 1
def func():
nonlocal count
print(count)
func()
# 反例
count = 1
def func():
print(count)
func()
2,可以内层函数对外层函数的局部变量进行修改。
def wrapper():
count = 1
def inner():
nonlocal count
count += 1
print(count)
inner()
print(count)
wrapper()
更多内容可以查看自己学python的过程,简单笔记。-CSDN博客
更多内容可以查看自己学python的过程,简单笔记。-CSDN博客
更多内容可以查看自己学python的过程,简单笔记。-CSDN博客