Python:Call-by-Value和Call-by-Object有什么区别?

cyt*_*nus 6 python arguments parameter-passing pass-by-value

许多人说在Python中,函数的参数是使用按值调用的模型传递的.据我所知,它实际上不是一种按值调用的语言,而是一种逐个调用或逐个调用的模型.

逐个值调用模型和逐个调用模型之间有什么区别?Python中的一个示例显示了这些模型的不同之处?

Mar*_*som 11

Python中的变量不是值,它们是对象引用.当您调用Python函数时,参数是对原始对象的引用的副本.我不知道这与你在问题中提出的术语有什么关系.

例如,考虑以下Python代码:

def foo(bar, baz):
    bar = 3
    baz[0] = 4

a = 1
b = [2]
foo(a, b)
print a, b
Run Code Online (Sandbox Code Playgroud)

a被分配给对象1,并被b分配给包含对象引用的列表对象2.在函数内部foo,bar也分配给同一个对象1baz分配给同一个列表对象.由于1是不可变的,因此无法更改对象,但可以重新分配bar以引用其他对象,例如3.列表是可修改的,因此通过设置baz[0],4您还可以更改b引用的列表对象.以上的输出将是1 [4].


new*_*cct 8

说它不是按值传递是不正确的.从语义上讲,它值传递,并且可以证明它与其他传值语言之间的语义等价.但是,它属于值为pass-by-value语言的特定子类别,其中所有值都是对象的引用(指针)(您不能将对象直接作为值),并且许多人将指向对象的指针与对象混淆本身.这些语言包括Java(关于对象),Python,Ruby,JavaScript,Scheme,Smalltalk,仅举几例.

令人困惑的是,不同语言的社区使用不同的术语.例如,Java社区始终将Java描述为按值传递,即使Java中的对象与Python和Ruby中的对象具有完全相同的语义.但是,在后面这些语言的社区中,你会听到"价值传递".

按值传递与按引用传递本质上是一种语义区别,而不是它的用途.但是许多(初学者)程序员并不关心语义,更关心它可以用来做什么.例如,有些人认为,只要你有"我有一些数据,我给一个功能,它可以改变它不还,我可以看到的变化",这意味着通过按参考,实际上并没有思考(关于改变的东西是你通过的东西,还是你通过的东西间接指出的东西.

"按对象传递"或"通过共享传递"或任何用于描述传值语义组合以及使所有值都为引用(指针)的术语.以这种方式,它们可以更容易地表达这种组合的实际效果,并且例如将其与C中的值传递的效果区分开.但从语义上讲,它仍然是价值传递.话说变量是"名"或"把手"是"绑定"到对象和当您分配或通过它,你分享的对象,是完全等同于说,变量(事实上,在语言的所有值)是指向对象的指针,当您指定或传递它们时,这些指针将按值复制.