在某些语言中,您可以使用特殊的保留字(如ref或val)通过引用或值传递参数.当您将参数传递给Python函数时,它永远不会在离开函数时改变参数的值.唯一的方法是使用全局保留字(或者我当前理解它).
例1:
k = 2
def foo (n):
n = n * n #clarity regarding comment below
square = n
return square
j = foo(k)
print j
print k
Run Code Online (Sandbox Code Playgroud)
会表现出来
>>4
>>2
Run Code Online (Sandbox Code Playgroud)
显示k是不变的
在此示例中,变量n永远不会更改
例2:
n = 0
def foo():
global n
n = n * n
return n
Run Code Online (Sandbox Code Playgroud)
在此示例中,变量n已更改
在Python中是否有任何方法可以调用函数并告诉Python 参数是值还是引用参数而不是使用全局?
其次,在A级剑桥考试,他们现在说一个函数返回一个单一而过程返回值超过一个值.在80年代,我被教导了一个函数有一个返回语句,而程序没有.为什么现在不正确?
Sho*_*rma 134
基本上有三种'函数调用':
Python是一种PASS-BY-OBJECT-REFERENCE编程语言.
首先,重要的是要理解一个变量,变量(对象)的值是两个独立的东西.变量'指向'对象.变量不是对象.再次:
变量不是对象
示例:在以下代码行中:
>>> x = []
Run Code Online (Sandbox Code Playgroud)
[]是空列表,x是指向空列表的变量,但x本身不是空列表
将变量(x,在上述情况下)视为一个框,将变量([])的"值"视为框内的对象.
通过对象引用(python中的情况):
这里,"对象引用按值传递".
def append_one(li):
li.append(1)
x = [0]
append_one(x)
print x
Run Code Online (Sandbox Code Playgroud)
这里,语句x = [0]产生一个指向对象[0]的变量x(box)
在被调用的函数上,创建了一个新的li.li的内容是SAME作为box x的内容.两个框都包含相同的对象.也就是说,两个变量都指向内存中的同一个对象.因此,li指向的对象的任何更改也将由x指向的对象反映.
总之,上述计划的产出将是:
[0,1]
注意:
如果在函数中重新分配变量li,则li将指向内存中的单独对象.但是,x将继续指向它之前指向的内存中的同一个对象.
例:
def append_one(li):
li = [0, 1]
x = [0]
append_one(x)
print x
Run Code Online (Sandbox Code Playgroud)
该计划的输出将是:
[0]
通过参考:
调用函数的框传递给被调用函数.隐含地,框的内容(变量的值)被传递给被调用的函数.因此,对被调用函数中的框内容的任何更改都将反映在调用函数中.
通过价值:
在被调用函数中创建一个新框,并将来自调用函数的框内容的副本存储到新框中.
希望这可以帮助.
dav*_*off 62
你不能通过Python中的引用传递一个简单的原语,但是你可以做以下事情:
def foo(y):
y[0] = y[0]**2
x = [5]
foo(x)
print x[0] # prints 25
Run Code Online (Sandbox Code Playgroud)
然而,这是一种奇怪的方式.请注意,在Python中,您还可以返回多个值,使得一些用于传递引用的用例不那么重要:
def foo(x, y):
return x**2, y**2
a = 1
b = 2
a, b = foo(a, b) # a == 2; b == 4
Run Code Online (Sandbox Code Playgroud)
当您返回这样的值时,它们将作为元组返回,而元组又被解压缩.
编辑: 另一种思考方式是,虽然您无法通过Python中的引用显式传递变量,但您可以修改传入的对象的属性.在我的示例(和其他)中,您可以修改列表的成员但是,你不能完全重新分配传入的变量.例如,看到以下两段代码看起来可能会做类似的事情,但结果会有不同的结果:
def clear_a(x):
x = []
def clear_b(x):
while x: x.pop()
z = [1,2,3]
clear_a(z) # z will not be changed
clear_b(z) # z will be emptied
Run Code Online (Sandbox Code Playgroud)
Kir*_*ser 24
好的,我会捅这个.Python通过对象引用传递,这与您通常认为的"通过引用"或"按值"不同.举个例子:
def foo(x):
print x
bar = 'some value'
foo(bar)
Run Code Online (Sandbox Code Playgroud)
因此,您要创建一个值为'some value'的字符串对象,并将其"绑定"到名为的变量bar
.在C中,这类似于bar
指向"某个值"的指针.
当你打电话时foo(bar)
,你不是在bar
自我传递.你传递bar
的是价值:指向"某种价值"的指针.此时,对同一个字符串对象有两个"指针".
现在比较一下:
def foo(x):
x = 'another value'
print x
bar = 'some value'
foo(bar)
Run Code Online (Sandbox Code Playgroud)
这就是差异所在.在线:
x = 'another value'
Run Code Online (Sandbox Code Playgroud)
你实际上并没有改变它的内容x
.事实上,这甚至都不可能.相反,您正在创建一个值为"另一个值"的新字符串对象.那个赋值算子?它并没有说" x
用新的价值覆盖东西".它说"更新x
指向新对象".在该行之后,有两个字符串对象:"某个值"(bar
指向它)和"另一个值"(x
指向它).
这并不笨拙.当您了解它的工作原理时,它就是一个优雅,高效的系统.
att*_*182 21
希望以下描述总结得很好:
这里有两件事要考虑 - 变量和对象.
例:
def changeval( myvar ):
myvar = 20;
print "values inside the function: ", myvar
return
myvar = 10;
changeval( myvar );
print "values outside the function: ", myvar
Run Code Online (Sandbox Code Playgroud)
O/P:
values inside the function: 20
values outside the function: 10
Run Code Online (Sandbox Code Playgroud)
例:
def changelist( mylist ):
mylist2=['a'];
mylist.append(mylist2);
print "values inside the function: ", mylist
return
mylist = [1,2,3];
changelist( mylist );
print "values outside the function: ", mylist
Run Code Online (Sandbox Code Playgroud)
O/P:
values inside the function: [1, 2, 3, ['a']]
values outside the function: [1, 2, 3, ['a']]
Run Code Online (Sandbox Code Playgroud)
例:
def changelist( mylist ):
mylist=['a'];
print "values inside the function: ", mylist
return
mylist = [1,2,3];
changelist( mylist );
print "values outside the function: ", mylist
Run Code Online (Sandbox Code Playgroud)
O/P:
values inside the function: ['a']
values outside the function: [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
从技术上讲,python 不按值传递参数:全部按引用传递。但是......由于python有两种类型的对象:不可变和可变,下面是发生的事情:
不可变参数通过值有效传递:字符串、整数、元组都是不可变对象类型。虽然它们在技术上是“通过引用传递”(就像所有参数一样),但由于您无法在函数内部就地更改它们,它看起来/行为就像通过值传递一样。
可变参数通过引用有效传递:列表或字典通过其指针传递。函数内部的任何就地更改(如(append 或 del))都会影响原始对象。
这就是 Python 的设计方式:没有副本,全部通过引用传递。您可以显式传递副本。
def sort(array):
# do sort
return array
data = [1, 2, 3]
sort(data[:]) # here you passed a copy
Run Code Online (Sandbox Code Playgroud)
最后一点我想提一下哪个函数有它自己的作用域。
def do_any_stuff_to_these_objects(a, b):
a = a * 2
del b['last_name']
number = 1 # immutable
hashmap = {'first_name' : 'john', 'last_name': 'legend'} # mutable
do_any_stuff_to_these_objects(number, hashmap)
print(number) # 1 , oh it should be 2 ! no a is changed inisde the function scope
print(hashmap) # {'first_name': 'john'}
Run Code Online (Sandbox Code Playgroud)
Python既不是按值传递也不是传递引用.它更像是"对象引用按值传递",如下所述:http://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick /.
这就是为什么它不是价值传递的原因. 因为
def append(list):
list.append(1)
list = [0]
reassign(list)
append(list)
返回[0,1]表明某种引用已明确传递,因为pass-by-value不允许函数根本改变父作用域.
胡先生,看起来像传递参考?不.
这就是为什么它不是传递参考.因为
def reassign(list):
list = [0,1]
list = [0]
重新分配(列表)
打印列表
返回[0],表示在重新分配列表时销毁了原始引用. pass-by-reference将返回[0,1].
有关更多信息,请访问:http://effbot.org/zone/call-by-object.htm
如果希望函数不操作外部作用域,则需要复制创建新对象的输入参数.
def append(list):
list.append(1)
list = [0]
reassign(list)
append(list)
Run Code Online (Sandbox Code Playgroud)