函数也是对象,内存底层分析
def g_test01(): print(2) g_test01() c = g_test01 c()
变量的作用域(全局变量和局部变量)
全局变量:在函数和类定义之外声明的变量,作用域为定义的模块,从定义位置开始直到模块结束
a = 3 # 全局变量 def Global_test(): b = 4 # 局部变量 global a # 如果要在函数中改变全局变量的值使用global a = 300 print(locals()) # 打印局部变量 print(globals()) # 打印全局变量(字典) Global_test()
局部变量和全局变量效率测试
局部变量的查询和访问速度比全局变量快,优先考虑使用,尤其在循环的时候
在特别强调效率的地方或者循环次数较多的地方,可以将全局变量转变为局部变量提高运行速度
import math import time def g_test01(): start = time.time() for i in range(1000000): math.sqrt(30) end = time.time() print('耗时{0}'.format(end - start)) def g_test02(): b = math.sqrt start = time.time() for j in range(1000000): b(30) end = time.time() print('耗时{0}'.format(end - start)) g_test01() g_test02()
参数的传递:函数的参数传递本质上是从实参到形参的赋值参数
python中一切皆对象,所有的赋值操作都是引用的赋值,参数的传递都是引用传递,不是值传递
可变对象:字典列表,集合,自定义对象等
传递可变对象
a = [10, 20] def g_test01(m): print(id(m)) m.append(30) print(id(m)) g_test01(a)
不可变对象:数字,字符串,元组,function等
a = 100 def G_test(n): print('n', id(n)) n = n + 100 print('n', id(n)) G_test(a)
浅拷贝和深拷贝
内置函数:copy(浅拷贝)deepcopy(深拷贝)
浅拷贝:不拷贝子对象的内容,只是拷贝子对象的引用,修改涉及到子对象,子对象一起修改
深拷贝:会连子对象的内存全部拷贝一份,对子对象的修改不会影响源对象
# 浅拷贝 a = [10, 20, [5, 6]] b = copy.copy(a) print(a) print(b) b.append(30) b[2].append(7) # 对子对象内容的修改影响源对象 print(a) print(b) # 深拷贝 a = [10, 20, [5, 6]] b = copy.deepcopy(a) b.append(30) b[2].append(7) # 对子对象内容修改不影响源对象 print(a) print(b)
参数传递不可变对象含可变对象
a = (10, 20, [5, 6]) print('a:', id(a)) def G_test(m): print('m:', id(m)) m[2][0] = 888 print(m) print(m, id(m)) G_test(a)
参数的几种类型
位置参数:需要个数和形参匹配,按位置传递参数
默认值参数:我们可以将某些参数设置默认值,这样这些参数在传递时就是可选的,成为‘默认值参数’,默认值参数必须在其他参数后面
命名参数:通过形参名称来匹配
def f1(a, b, c, d): print('{0}-{1}-{2}-{3}'.format(a, b, c, d)) f1(10, 20, 30, 40) # 位置参数,个数不匹配报错 f1(d=15, b=100, a=10, c=11) # 命名参数,通过形参名称来匹配 def f2(a, b, c=10, d=15): # 默认参数必须位于其他参数后面 print('{0}-{1}-{2}-{3}'.format(a, b, c, d)) f2(1, 3, 4)
可变参数
1.一个星号,将多个参数收集到一个元组对象中
2.两个星号,将多个参数收集到一个字典对象中
星号后添加参数必须定义命名参数
def f1(a, b, *c): # 元组 print('{0}-{1}-{2}'.format(a, b, c)) f1(1, 2, 3, 4, 5) def f2(a, b, *d, **c): # 元组必须在字典之前 print('{0}-{1}-{2}-{3}'.format(a, b, d, c)) f2(1, 2, name='zf', age=18) def f3(*a, b, c): #可变参数后面增加新参数必须定义为命名参数 print('{0}-{1}-{2}'.format(a, b, c)) f3(1, 2, b=3, c=4)
lambda表达式和匿名函数
f = lambda a, b, c, d: a * b * c * d print(f(1, 2, 3, 4)) f1 = [lambda a: a * 2, lambda b: b * 3] print(f1[0](2), f1[1](3))
eval函数
将字符串str当成有效表达式来求值并返回计算结果
语法eval(source,globals,locals)
source:一个python表达式或者函数
globals:可选必须是字典dict
locals:任意映射对象
eval('print("hello")') a = 10 b = 20 print(eval('a+b')) dict1 = dict(a=100, b=200) d = eval('a+b', dict1) print(d)
递归函数
def g_test01(n): print('g_test01:', n) if n == 0: print('over') else: g_test01(n - 1) print('g_test01****', n) g_test01(4)