python学习笔记——函数及内存分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

返回值return

还可以结束函数的运行
在这里插入图片描述

def my_avg(a, b):
    return (a + b) / 2


c = my_avg(20, 30)
print(c)
25.0

在这里插入图片描述

def add(a, b):
    print("计算两个参数{0},{1}的和:{2}".format(a, b, (a + b)))
    return a + b


def text02(x, y, z):
    return [x ** 2, y ** 2, z ** 2]


c = add(20, 30)
print(c)
d = text02(2, 3, 4)
print(d)
50
[4, 9, 16]

局部变量全局变量

局部变量a与全局变量a是完全两个对象,函数里优先只局部变量
在这里插入图片描述

参数的传递_传递可变对象_内存分析

可变对象

a = [10, 20]
print(id(a))
print(a)
print("*****************************************")

def test01(m):
    print(id(m))
    m.append(300)
    print(id(m))  # 由于a是可变对象,所以m地址不变

test01(a)
print(a)
2144395747912
[10, 20]
*****************************************
2144395747912
2144395747912
[10, 20, 300]

注:

  1. a是一个栈,相对应数据值存在堆中;m是一个栈帧,相对应数据值也存在堆中
  2. 如果调用函数,会启动一个栈帧m,结束后即消失
  3. m是局部变量,调用时m与a的地址一模一样
  4. 由于此处a是可变对象,所以可修改

参数的传递_传递不可变对象_内存分析

a = 100
def f1(n):
    print("n:", id(n))  # 传递进来的是a对象的地址
    n = n + 200  # 由于a是不可变对象,因此创建新的对象n(id不同)
    print("n:",id(n))  # n已经变成了新的对象
    print(n)
f1(a)
print("a:",id(a))
n: 140706869780384
n: 2288594194384  # 输出地址变了,不再是原来的n了
300
a: 140706869780384

浅拷贝和深拷贝_内存分析

浅拷贝:只拷贝对象本身,不包含该对象引用的其他对象
深拷贝:连带该对象引用的所有相关的对象(儿子孙子家庭)全拷贝

import copy

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)
a: [10, 20, [5, 6]]
b: [10, 20, [5, 6]]
浅拷贝……
a: [10, 20, [5, 6, 7]]  # b中包含的下一子对象依旧是a中的,
b: [10, 20, [5, 6, 7], 30]  # 改b中该对象即a中的

在这里插入图片描述

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)
a: [10, 20, [5, 6]]
b: [10, 20, [5, 6]]
深拷贝……
a: [10, 20, [5, 6]]
b: [10, 20, [5, 6, 7], 30]

深拷贝则全部拷贝了过来,b怎么改都不会影响到a了

参数的传递_不可变对象含可变子对象_内存分析


a = (10, 20, [5, 6])
print("a:", id(a))

def test01(m):
    print("m:", id(m))
    m[0] = 20  # 这样会报错,元组不可变
    print(m)
    print("m:", id(m))


test01(a)

传递不可变对象时,如果包含的子对象是可变的,则可修改


a = (10, 20, [5, 6])
print("a:", id(a))

def test01(m):
    print("m:", id(m))
    m[2][0] = 888  # 改变元组内层列表元素的值
    print(m)
    print("m:", id(m))


test01(a)
print(a)
a: 1925259481304
m: 1925259481304  # m的id不变,仍是那个对象
(10, 20, [888, 6])
m: 1925259481304
(10, 20, [888, 6])  # a也跟随m的变化改变了

在这里插入图片描述
注:绿色圈圈包含的是不可修改的

参数的几种类型

位置参数

默认值参数

def test01(a, b = 10, c = 20)# 默认值参数必须位于普通位置参数后面
    print(a,b,c)

test01(8,9,19)  # 可通过传递新值覆盖默认值

命名参数

def f1(a, b, c):
    print(a, b, c)


f1(8, 9, 10)  # 位置参数
f1(c=10, a=20, b=30)  # 命名参数

可变参数

指可变数量的参数

def f1(a,b,*c)  # 将多个参数收集到一个元组c中
    print(a,b,c)

f1(8,9,19,20)  # 将19,20收集到c中
def f2(a,b,**c)  # # 将多个参数收集到一个字典c中
    print(a,b,c)

f1(8,9,name='celia',age=20)
def f2(a,b,*d,**c):  # 注意顺序是先元组后字典
    print(a,b,c,d)

f1(8,9,30,40,name='celia',age=20)

强制命名参数

可变参数后如果还要加参数,需要强制命名

def f2(*d, a, b):
    print(a, b, d)


f2(8, 9, a=30, b=40)

lambda表达式和匿名函数

在这里插入图片描述

在这里插入代码片

eval()函数用法

可从外部传进来

递归函数_函数调用内存分析_栈帧的创建

递归函数:自己调用自己的函数,在函数内部直接或间接的自己调用自己
先执行的后调用

嵌套函数_内部函数_数据隐藏

nonlocal关键字(似global)

nonlocal声明外层局部变量内层函数想使用外层函数中的变量通常情况下,内层函数可以调用外层函数的变量,但是不能修改

LEGB规则

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值