📜  Python是按引用调用还是按值调用

📅  最后修改于: 2022-05-13 01:54:53.813000             🧑  作者: Mango

Python是按引用调用还是按值调用

Python使用了一个系统,称为“通过对象引用调用”或“通过赋值调用”。如果您将整数、字符串或元组等参数传递给函数,则传递就像按值调用一样,因为您无法更改传递给函数的不可变对象的值。而传递可变对象可以被认为是通过引用调用,因为当它们的值在函数内部发生变化时,它也会在函数外部反映出来。
示例 1:

Python3
# Python code to demonstrate
# call by value
 
 
string = "Geeks"
 
 
def test(string):
     
    string = "GeeksforGeeks"
    print("Inside Function:", string)
     
# Driver's code
test(string)
print("Outside Function:", string)


Python3
# Python code to demonstrate
# call by reference
 
 
def add_more(list):
    list.append(50)
    print("Inside Function", list)
 
# Driver's code
mylist = [10,20,30,40]
 
add_more(mylist)
print("Outside Function:", mylist)


Python3
a = "first"
b = "first"
 
 
# Returns the actual location
# where the variable is stored
print(id(a))
 
# Returns the actual location
# where the variable is stored
print(id(b))
 
# Returns true if both the variables
# are stored in same location
print(a is b)


Python3
a = [10, 20, 30]
b = [10, 20, 30]
 
# return the location
# where the variable
# is stored
print(id(a))
 
# return the location
# where the variable
# is stored
print(id(b))
 
# returns false if the
# location is not same
print(a is b)


Python3
def foo(a):
     
    # A new variable is assigned
    # for the new string
    a = "new value"
    print("Inside Function:", a)
     
     
# Driver's code
string = "old value"
foo(string)
 
print("Outside Function:", string)


Python3
def foo(a):
    a[0] = "Nothing"
     
# Driver' code
bar = ['Hi', 'how', 'are', 'you', 'doing']
foo(bar)
print(bar)


输出

Inside Function: GeeksforGeeks
Outside Function: Geeks

示例 2

Python3

# Python code to demonstrate
# call by reference
 
 
def add_more(list):
    list.append(50)
    print("Inside Function", list)
 
# Driver's code
mylist = [10,20,30,40]
 
add_more(mylist)
print("Outside Function:", mylist)

输出

Inside Function [10, 20, 30, 40, 50]
Outside Function: [10, 20, 30, 40, 50]

将名称绑定到对象

在Python中,我们为其分配值/容器的每个变量都被视为一个对象。当我们给一个变量赋值时,我们实际上是把一个名字绑定到一个对象上。

Python3

a = "first"
b = "first"
 
 
# Returns the actual location
# where the variable is stored
print(id(a))
 
# Returns the actual location
# where the variable is stored
print(id(b))
 
# Returns true if both the variables
# are stored in same location
print(a is b)

输出

110001234557894
110001234557894
True

现在,让我们尝试通过另一个示例更好地理解这一点。
示例 2:

Python3

a = [10, 20, 30]
b = [10, 20, 30]
 
# return the location
# where the variable
# is stored
print(id(a))
 
# return the location
# where the variable
# is stored
print(id(b))
 
# returns false if the
# location is not same
print(a is b)

输出

541190289536222
541190288737777
False

上述两个示例的输出不同,因为列表是可变的,而字符串是不可变的。不可变变量一旦创建就无法更改。如果我们希望更改不可变变量,例如字符串,我们必须创建一个新实例并将变量绑定到新实例。然而,可变变量可以就地更改。
示例 3:

Python3

def foo(a):
     
    # A new variable is assigned
    # for the new string
    a = "new value"
    print("Inside Function:", a)
     
     
# Driver's code
string = "old value"
foo(string)
 
print("Outside Function:", string)

输出:

Inside Function: new value
Outside Function: old value

在上面的示例中,作为不可变对象类型的字符串作为参数传递给函数foo。在给定函数foo 的范围内,a=“新值”已绑定到字符串已绑定到外部的同一对象。在函数foo 的范围内,我们将“旧值”修改为“新值”。一旦我们离开函数foo 的范围,a=”new value” 就不再在名称空间中,并且字符串所指的值永远不会改变。
示例 4:现在,让我们看看可变变量是如何传递给函数的。

Python3

def foo(a):
    a[0] = "Nothing"
     
# Driver' code
bar = ['Hi', 'how', 'are', 'you', 'doing']
foo(bar)
print(bar)

输出:

['Nothing, 'how', 'are', 'you', 'doing']

当我们将可变变量传递给函数foo 并将其修改为其他名称时,函数foo 仍然指向该对象,并在执行期间继续指向该对象。