为回答网友问题,而造此博文

# def spam(eggs):
#     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........

初学...表达能力有限,希望有所帮助.















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值