# eggs.append(1)
# eggs = [2, 3]
#
# ham = [0]
# spam(ham)
# print(ham)
#1.首先对你看的博文中的代码进行等价改动 --- 个人代码习惯问题
ham = [0]
def span(eggs):
eggs.append(1)
eggs = [2, 3]
spam(ham)
print(ham)
先科普下原理性的只是 --- 来自官方API
1.python中函数定义是一个可执行语句(逻辑语句,而不是物理语句),函数的执行绑定当前本地命名空间中的函数名和一个函数对象(围绕该函数可执行代码的包装器).函数对象中包含一个对当前全局命名空间的一个引用,当该函数被调用,该引用被当做全局命名空间使用(意思是可以引用全局命名空间中的内容)
函数的执行(即被调用/加载到内存),会为该函数创建一个新的本地符号表,更确切来说,函数中所有变量的赋值都会把值存储在本地符号表中,当变量被应用是查找顺序:
当前(被调)函数本地符号表 --> 主调函数本地符号表 --> 全局符号表
--> python内置符号表(python解释器启动时也是需要加载一些常量啊什么的[e.g:quit(), exit()等]).
因此,全局变量不能在函数内部被赋值(除非使用golable关键字进行相关操作....).....这句废话不翻译了....
第二段: 走起
函数被调用时,实参会被引入到被调函数的本地符号表中,因此参数传递时"值传递"(这三个字不准确,看箭头)(该值指的是对象的引用的值,不是对象的值),当一个函数被调用会为该函数创建一个新的本地符号表
红箭头解释部分:
更准确的描述是参数传递的是对象引用,后一句.....不理解啥意思.......
本人,也是初学....只是对API多瞄了几眼,希望能从本质上理解python,所以这样答问.....不知喜否?
科普完毕,下面来具体分析你的代码
ham = [0]
def span(eggs):
eggs.append(1)
eggs = [2, 3]
span(ham)
print(ham)
spam(ham)
调用该函数,把ham赋值给eggs --- 这也是上文说的函数内部的赋值行为,因而会把实参ham引入到函数span的本地符号表,在执行eggs.append(1)时,首先在本地符号表中找到ham,然后在声明ham时ham被引入的符号表中找到ham,找到后当然是向ham列表实体中追加元素1了...over
eggs = [2,3]
这句执行后,eggs即当前函数本地符号表中的ham不再指向声明ham时ham被引入的符号表中的ham,而指向列表[2, 3]实体,即这句执行并没有改变ham所在符号表中的ham,只是创建了一个新的列表,并且改变了当前函数span符号表中ham即eggs的指向
print(ham)
执行这句时,即调用print函数,ham也会被引入到print函数的本地符号表,在print函数内部把ham写入到流中时,会在print函数内部本地符号表中找到ham,然后在声明ham时ham被引入的符号表中找到ham,并把ham写入流中,输出到屏幕
此时找到的ham中内容被span函数追加了一个元素,其元素为[0,1]
............over....................over....................over....................over....................over....................over........
初学...表达能力有限,希望有所帮助.