文章目录
一、函数
1.函数的定义和调用
1)定义-基本概念
函数是可重用的程序代码块。函数代表一个任务或一个功能。
函数不仅能实现代码的重用,更能实现代码的一致性。
2)函数的分类

3)函数的调用
定义函数的语法如下:
def 函数名([参数列表]):
'''文档字符串‘’’
函数体/若干语句
要点:
1.执行def函数,会创建一个函数对象,并绑定到函数名变量上

2.参数列表

3.return返回值

4.调用函数前需先定义函数,
1)内置函数对象会自动创建
2)标准库和第三方库函数,通过import导入模块,会执行模块中的def语句
4)形参和实参
形式参数是在定义函数时使用的,命名只要符合“标识符规则即可”
实际参数调用函数时传入的参数
5)文档字符串-函数注释
通过三个单引号或单个多引号来实现,中间可以加入多行文字进行说明
打印文档字符串
help(函数名.__doc__) #打印输出函数的文档字符串
6)返回值

7)函数也是对象、
def fun1():
print("我是函数fun1")
f = fun1
f()
内存底层分析

2.变量的作用域
不同作用域内的同名变量之间互不影响。
变量分为全局变量和局部变量

1)栈帧内存分析
#测试全局变量和局部变量
a = 3
def fun():
b = 4
print(b*10)
fun()

蓝框局部变量b所在位置为栈帧,每次调用函数就会启动栈帧,调用完后删除栈帧。再次调用再次启动栈帧(stark frame)
2)global关键字
#测试全局变量和局部变量
a = 3
def fun():
b = 4
print(b*10)
global a #如果要在函数内改变全局变量的值,增加global关键字说明
a = 300
print(a)
print(locals()) #打印输出局部变量
print(globals()) #打印输出全局变量
fun()
>>>
40
300
{'b': 4}
{'__name__': '__main__', '__doc__': '\n@author: admin\n@file: test1.py\n@time: 2020/06/27\n@desc:\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001BD4DFD1CC0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/PycharmProjects/MyTest/Day_55/test1.py', '__cached__': None, 'a': 300, 'fun': <function fun at 0x000001BD4E00C268>}
3)局部变量和全局变量的效率测试
局部变量的查询和访问速度比全局变量快,优先考虑使用。
在特别强调效率的地方或者循环次数较多的地方,可以将全局变量转换为局部变量提高速度。
import math
import time
def fun1():
start = time.time()
for i in range(10000000):
math.sqrt(30)
end = time.time()
print("耗时{}".format(end-start))
def fun2():
b = math.sqrt #局部变量
start = time.time()
for i in range(10000000):
b(30)
end = time.time()
print("耗时{}".format(end - start))
fun1()
fun2()
>>>
耗时1.2167448997497559
耗时0.8946514129638672
3.参数的传递
函数参数传递本质山是从实参到形参的赋值操作。python一切皆对象,所有赋值操作都是“引用的赋值”

1)传递可变对象的引用
传递的参数是可变对象时,在函数体中不创建新的对象拷贝,而是可以直接修改所传递的对象。
#测试参数的传递-传递可变对象-直接修改所传递的对象
a = [10,20]
print(a)
def fun1(m):
print("局部变量m的地址是{}".format(id(m)))
m.append(30)
fun1(a)
print("全局变量a的地址是{}".format(id(a)))
print(a)
>>>
[10, 20]
局部变量m的地址是2229871600200
全局变量a的地址是2229871600200
[10, 20, 30]

2)传递不可变对象的引用
传递参数是不可变对象,在"赋值操作"时,由于不可变对象无法修改,系统会新创建一个对象。


3)不可变对象中含可变对象
#测试参数传递_不可变对象中含子可变对象,则方法内修改了这个可变对象,原对象也发生了改变
a = (5,6,[7,8])
def fun1(m):
print(m)
print("m:",id(m))
m[2][0] = 666
print(m)
print("m:",id(m))
fun1(a)
print(a)
print("a:",id(a))
>>>
(5, 6, [7, 8])
m: 2979154990424
(5, 6, [666, 8])
m: 2979154990424
(5, 6, [666, 8])
a: 2979154990424

4)浅拷贝和深拷贝及内存分析

浅拷贝及内存分析
import copy
def testCopy():
'''测试浅拷贝'''
a = [10,20,[5,6]]
b = copy.copy(a)
print("a:",a)
print("b:",b)
b.append(30)
b[2].append(7)
print("浅拷贝.....")
print("a:",a)
print("b:",b)
testCopy()
>>>
a: [10, 20, [5, 6]]
b: [10, 20, [5, 6]]
浅拷贝.....
a: [10, 20, [5, 6, 7]]
b: [10, 20, [5, 6, 7], 30]

深拷贝及内存分析
#测试深拷贝
import copy
def testDeepCopy():
'''测试深拷贝'''
a = [10,20,[5,6]]
b = copy.deepcopy(a)
print("a:",a)
print("b:",b)
b.append(30)
b[2].append(7)
print("深拷贝.....")
print("a:",a)
print("b:",b)
testDeepCopy()
>>>
a: [10, 20, [5, 6]]
b: [10, 20, [5, 6]]
深拷贝.....
a: [10, 20, [5, 6]]
b: [10, 20, [5, 6, 7], 30]

4.参数的类型
1)位置参数
函数调用时,实参默认按位置顺序传递,需要个数与形参匹配
2)默认值参数

3)命名参数-关键字参数
按照形参的名称传递参数,称为关键字参数
4)可变参数-收集参数

5)强制命名参数
在“可变参数”后增加参数,必须在调用的时候强制命名参数

5.匿名函数-lambda表达式

6.eval()函数

#测试eval()函数
s = "print('i love fishc.com')"
eval(s) #动态的改变结构
>>>
i love fishc.com
dict1 = dict(a= 100,b = 200)
d = eval("a+b",dict1)
print(d)
>>>
300
7.递归函数及内存分析
def:在函数体内部直接或间接自己调用自己
递归函数会创建大量的函数对象,,过量的消耗运算和内存能力
组成部分:
1.终止条件
表示递归时候结束,一般用于返回值,不再调用自己。
2.递归步骤
把第n步的值与第n-1步相关联
#测试递归函数的基本原理
def fun1(n):
print("fun1",n)
if n == 0:
print("over")
else:
fun1(n-1)
print("fun1***",n)
fun1(4)
>>>
fun1 4
fun1 3
fun1 2
fun1 1
fun1 0
over
fun1*** 0
fun1*** 1
fun1*** 2
fun1*** 3
fun1*** 4

阶梯计算
#使用递归函数计算阶乘
def factorial(n):
if n == 1:
return 1
else:
return n*factorial(n-1)
f = factorial(5)
print(f)
>>>
120

8.嵌套函数_数据隐藏

避免代码重复:

9.nonlocal_global
nonlocal用来声明外层的局部变量
global用来声明全局变量
可以访问但不能修改,要想修改则使用nonlocal和global关键字。
a = 20
def outer():
b = 10
def inner():
nonlocal b #声明外部函数的局部变量
print("inner b",b)
b += 10
print("outer b", b)
global a #声明全局变量
a += 10
inner()
outer()
print("a:",a)
>>>
inner b 10
outer b 20
a: 30
10.LEGB规则

本文详细探讨了Python函数的基础,包括函数的定义、调用,以及参数的传递方式。重点介绍了函数的作用域、变量的局部与全局、参数的默认值、关键字参数、可变参数等特性。还涵盖了匿名函数lambda、递归函数的内存分析以及LEGB规则,帮助读者全面掌握Python函数的使用。


被折叠的 条评论
为什么被折叠?



