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
绑定整数对象池中的一个整形对象
1 | |

1是一个对象,在整数对象池中是固定的(即一个特定的内存位置存储着1),如上一三两行实现了ac均绑定了整数对象1,第二行意为将a绑定的对象也绑到b上,如此,abc均绑定了对象1,所以显示相同的地址
小整数对象池和大整数对象池
整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间。
Python 对小整数的定义是 [-5, 256] 这些整数对象是提前建立好的,不会被垃圾回收。在一个 Python 的程序中,无论这个整数处于LEGB中的哪个位置,所有位于这个范围内的整数使用的都是同一个对象。同理,单个字母也是这样的。
大整数对象池。说明:终端是每次执行一次,所以每次的大整数都重新创建,而在pycharm中,每次运行是所有代码都加载都内存中,属于一个整体,所以这个时候会有一个大整数对象池,即处于一个代码块的大整数是同一个对象。
——引自:python中小整数对象池和大整数对象池
is是判断是否是同一个对象的操作符,返回值是布尔型;类似于:两个人是一个人等价于两个人的身份证号码相同(如果都有身份证),两个变量绑定了相同的对象 <==> id(变量1) == id(变量2)



赋值list
绑定一个list对象给变量
1 | |

#1 和 #2展示了:对于构造一个可变类型的对象并绑定给变量,无论当前是否有和其暂态相同的对象,都会创建新的对象,而不使用旧的对象。因为它是可变类型,有无限的可能(增删改),暂态相同并不代表永远相同,所以是否相同是不确定的事情,而python或是说程序永远不会去做不确定的事儿。这是与不可变对象的区别。
#3 是将b绑定的对象给c绑定上,即bc绑定了同一个对象,那么对c的操作必定会影响对b的操作
#4 是对c进行了操作,进而影响了b, 因为对c的append()追加元素操作,实际上是bc共同绑定的对象的追加变更,很多人称python可变对象的这个特点跟C++的引用一样,其实是不准确和错误的。学python的确可以借鉴C++,但不应照单全收,因为两者的机制有非常大的区别。
高级赋值操作
批量赋值
1 | |

拆包与装包
1 | |

python传参
python的传参过程与赋值过程类似(更像是实参给形参批量赋值),实质也是对象的绑定
C++有传值,传引用,python的参数传递是?就叫他 传对象 吧!
传不可变对象
1 | |

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++的值传递一样
传可变对象
1 | |

这里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++里的引用传递一样
默认值参数
1 | |

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

*args作为形参时是用来接收多余的未命名参数,而**kwargs是用来接收key=value这种类型的命名参数,args是元组,kwargs是字典。
拆装包实现对象的拷贝
1 | |

1 | |

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