python 传参 空值_python传参和赋值

python的赋值

Assignment statements are used to (re)bind names to values and to modify attributes or items of mutable objects ------官方文档

赋值语句用于(重新)将名称绑定到值,并修改可变对象的属性或项

python中一切皆对象,数字是对象,列表是对象,函数是对象

简单理解,python的变量可以看作一个简简单单的“标签”,除了变量名没有任何意义,直到它被一个有意义的实体(对象)所赋值,赋值的过程其实就是一个变量绑定对象的过程,可以看作是给对象贴了个标签(这个比喻相对严谨)

赋值过程

无论是可变类型(如list)的对象或是不可变类型(如int)的对象, 给变量赋值的过程都意味着绑定或重新绑定

绑定过程不是只有一次,绑定过对象的变量仍可以重新绑定其它对象(包括其它类型的对象),没有被变量绑定的对象将可能被垃圾回收

赋值int

绑定整数对象池中的一个整形对象

a = 1

b = a

c = 1

d = 2

print("a",id(a))

print("b",id(b))

print("c",id(c))

print("d",id(d))

1是一个对象,在整数对象池中是固定的(即一个特定的内存位置存储着1),如上一三两行实现了ac均绑定了整数对象1,第二行意为将a绑定的对象也绑到b上,如此,abc均绑定了对象1,所以显示相同的地址

小整数对象池和大整数对象池

整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间。

Python 对小整数的定义是 [-5, 256] 这些整数对象是提前建立好的,不会被垃圾回收。在一个 Python 的程序中,无论这个整数处于LEGB中的哪个位置,所有位于这个范围内的整数使用的都是同一个对象。同理,单个字母也是这样的。

大整数对象池。说明:终端是每次执行一次,所以每次的大整数都重新创建,而在pycharm中,每次运行是所有代码都加载都内存中,属于一个整体,所以这个时候会有一个大整数对象池,即处于一个代码块的大整数是同一个对象。

is是判断是否是同一个对象的操作符,返回值是布尔型;类似于:两个人是一个人等价于两个人的身份证号码相同(如果都有身份证),两个变量绑定了相同的对象 <==> id(变量1) == id(变量2)

赋值list

绑定一个list对象给变量

# 1

a = []

b = []

print("a is b?",a is b)

#2

goo = [1,2,3]

gll = [1,2,3]

gtt = [1,2,3,4]

print(id(goo),id(gll),id(gtt))

#3

c = b

print("c is b?",c is b)

#4

c.append(1)

print("c:",c)

print("b:",b)

#1 和 #2展示了:对于构造一个可变类型的对象并绑定给变量,无论当前是否有和其暂态相同的对象,都会创建新的对象,而不使用旧的对象。因为它是可变类型,有无限的可能(增删改),暂态相同并不代表永远相同,所以是否相同是不确定的事情,而python或是说程序永远不会去做不确定的事儿。这是与不可变对象的区别。

#3 是将b绑定的对象给c绑定上,即bc绑定了同一个对象,那么对c的操作必定会影响对b的操作

#4 是对c进行了操作,进而影响了b, 因为对c的append()追加元素操作,实际上是bc共同绑定的对象的追加变更,很多人称python可变对象的这个特点跟C++的引用一样,其实是不准确和错误的。学python的确可以借鉴C++,但不应照单全收,因为两者的机制有非常大的区别。

高级赋值操作

批量赋值

a,b,c = 1,2,3

print(a)

print(b)

print(c)

拆包与装包

# 装包:按位置将变量赋值后多余的装列表里

a,b,*c,d = 1,2,3,4,5,6

print(a,b,c,d)

# 拆包:打开列表取出值

print(*c)

python传参

python的传参过程与赋值过程类似(更像是实参给形参批量赋值),实质也是对象的绑定

C++有传值,传引用,python的参数传递是?就叫他 传对象 吧!

传不可变对象

def give_me_a_num(a):

a = a+1

print("give_me_a_num's a:",a)

def main():

a = 1

print("main's origin a:",a)

give_me_a_num(a)

print("main's a:",a)

main()

a在main里是绑定的整数1,传过去给give_a_num的a, 说你也绑定这个对象吧,于是give_me_a_num里的a的值是1,

接着give_me_a_num里发生了状况,里面的a不喜欢1这个对象了,舍弃,重新绑定了对象a+1,也就是2,

而main里的a一直对1不离不弃,所以这个a一直是1

这样一气呵成,并没什么不妥;但很多人看了这个以后断定:python的参数传递和C++的值传递一样

传可变对象

def give_me_a_girl(girl):

girl["lover"] = "Mike"

print("give_me_a_girl's girl:\n\t",girl)

def main():

girl = {"name":"Mark","age":20,"lover":"Tim"}

print("main's origin girl:\n\t",girl)

give_me_a_girl(girl)

print("main's girl:\n\t",girl)

print("\nTim:\"Mark,you changed!You don't love me anymore.\"")

main()

这里girl是一个字典,是一个可变对象,main里面的变量girl绑定了这个对象,传给了give_me_a_girl里的girl,它也绑定了这个对象,并且对所绑定的对象做了相应的修改,因为main和give_me_a_gril里的girl绑定的是同一个对象,所以main's girl也是改变了的,本质是其绑定的对象发生了改变。

这是python传可变对象的实质,如果give_me_a_girl里面的girl重新绑定了新的对象,再做变化,就不会再影响到main's girl了;但是很多人看了这种实例,就断言:python传参方式和C++里的引用传递一样

默认值参数

def make_cake(cream,butter = 0,fruit = 3):

print("做了蛋糕")

print("奶油{}斤,黄油{}两,水果{}块".format(cream,butter,fruit))

make_cake(1,3)

make_cake(1,2,4)

make_cake(4)

make_cake(2,fruit = 8) #python比较高级的地方

make_cake()的使用比较方便,有两个默认参数,传参时第一个实参不可省,确认是给cream的,剩下两个可以按顺序给或不给(默认),使用key=value的方式可以打破顺序

拆包装包实现可变参数的函数

def get(git_id,*args,**kwargs): #git_id要写前面,否则贪婪匹配,不会给它剩

print("装包后:")

print("git_id:",git_id)

print("args:",args)

print("kwargs:",kwargs)

print("对传过来的参数拆包:".format())

print("*args:",*args)

print("kwargs拆包后传给fun:",end="")

fun(**kwargs) #相当于fun(a=1,b=2)

def fun(b,a): #注意键名和参数名对应

print(a,b)

get(1,2,3,4,5,6,a=1,b=2) #调用时前面第一个之后装包给元组,剩下给字典

*args作为形参时是用来接收多余的未命名参数,而**kwargs是用来接收key=value这种类型的命名参数,args是元组,kwargs是字典。

拆装包实现对象的拷贝

# 方便的使用方法

def rich(*money):

print("今天赚了{}元钱".format(sum(money)))

rich(2,3,4,5)

def rich(*money):

print(id(money))

print("今天赚了{}元钱".format(sum(money)))

def main():

today_come = [1,2,3,4,5,6]

print(id(today_come))

rich(*today_come)

main()

可以看到rich()‘s money和 main()’s today_come 的id不一样,也就是两者没有绑定一样的对象了,因为拆包后会装到一个新的包里,这样互相就不影响了

想到这里,,,

def give_me_a_girl(**girl):

girl["lover"] = "Mike"

print("give_me_a_girl's socalled girl:\n\t",girl)

def main():

girl = {"name":"Mark","age":20,"lover":"Tim"}

print("Tim's origin girl:\n\t",girl)

give_me_a_girl(**girl)

print("Tim's normal girl:\n\t",girl)

print("\nTim: \"I love you,Mark!\"")

main()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值