从模块 (Python) 的调用函数传递值
Passing value from called function from module (Python)
我正在尝试从另一个名为 "File1" 的文件调用函数 passvalue
作为 "Main File" 的模块。我希望 "Main File" 中的 x
的值是 4 而不是 1,并且 y
的值在调用函数后是 3 而不是 2。
问题:我如何确保来自 "File1" 的模块函数的值被传递到 "Main File"?对于这种情况,x=4
和 y=3
.
我的想法:我尝试使用全局值,但它似乎不起作用,return 在这种情况下只会 return x
或 y
值回到函数本身,这可能会破坏目的。
感觉好像我错过了一些简单的东西,但似乎无法理解。
文件 1:
def passvalue(a,b)
b=b+a
a=b+b
主要:
import File1
x=1
y=2
File1.passvalue(x,y)
print(x)
print(y)
您需要 return
如下值:
def passvalue(a,b)
b=b+a
a=b+b
return a, b
这个returns一个tuple
. The tuple
can the unpacked喜欢:
# Main File
import File1
x=1
y=2
x, y = File1.passvalue(x,y)
print(x)
print(y)
它不起作用的原因有多种:
首先,函数中分配的对象是本地创建的。当您执行 a=...
和 b=...
时,a
和 b
是您在分配给参数的函数中创建的 local 对象值。函数退出后,a
和 b
不再与直接函数作用域外的代码保持任何相关性。
其次,当对象在 Python 中通过 引用 传递时,保持不变的是不可变的。由于 x
和 y
是整数,它们是不可改变的,即每次你对它们执行任何操作时,一个新值被 分配 给对象而不是它改变了。
要理解这一点,请考虑以下函数:
def mod_lists(list_1, list_2, list_3):
print("obj ID of rlst_1 = {0}\n"
"obj ID of rlst_2 = {1}\n"
"obj ID of rlst_3 = {2}\n".format(id(rlst_1), id(rlst_2), id(rlst_3)))
print("Before change:\n"
"obj ID of list_1 = {0}\n"
"obj ID of list_2 = {1}\n"
"obj ID of list_3 = {2}\n".format(id(list_1), id(list_2), id(list_3)))
list_1.append("hello")
list_2 = list_1 + ["world"]
list_3 = list_1 + ["world"]
print("After change:\n"
"obj ID of list_1 = {0}\n"
"obj ID of list_2 = {1}\n"
"obj ID of list_3 = {2}\n".format(id(list_1), id(list_2), id(list_3)))
return list_3
现在考虑我要传递三个 list
s:
rlst_1 = list()
rlst_2 = list()
rlst_3 = list()
我调用函数如下:
rlst_3 = mod_lists(rlst_1, rlst_2, rlst_3)
现在您可能期望 rlst_1 = ['hello']
、rlst_2 = ['hello', 'world']
和 rlst_3 = ['hello', 'world']
,但这是错误的。如果你 运行 它,你会注意到 rlst_2
实际上是一个空 list
(不变)。
那么是什么让 rlst_1
和 rlst_3
发生了变化?我们看一下打印出来的对象ID,对比一下:
# NOTE: You will see different numbers on your system.
obj ID of rlst_1 = 52178816
obj ID of rlst_2 = 52337240
obj ID of rlst_3 = 51607312
Before change:
obj ID of list_1 = 52178816
obj ID of list_2 = 52337240
obj ID of list_3 = 51607312
After change:
obj ID of list_1 = 52178816
obj ID of list_2 = 52336920
obj ID of list_3 = 52336840
在函数中进行任何更改之前,您可以看到对象 ID 分别 完全相同,这意味着 list_1
是 [= 的精确引用30=],等。现在,在完成更改后,您会注意到更改。您可以看到 list_2
和 list_3
现在具有不同的对象 ID。这是为什么?那是因为在 list_2=...
和 list_3=...
行中,您有效地 将两个对象重新分配 到一个新引用,即 list_1 + ['world']
。您可能还想知道为什么它们都有不同的 ID,因为值应该相同。虽然 list_1
是相同的引用,但每个 ['world']
都是 list
对象的 新实例 ,其中包含单词 "world"
作为项目, 所以它们是不同的对象,即使它们具有相同的值。
为什么 list_1
的对象引用没有受到影响?这是因为当您在 list_1
上调用 append
函数时,它不会 重新分配 而是更改引用中的对象,附加值 "hello"
进入同一个对象。
函数调用后,打印 rlst
时,您将看到:
# rlst_1
# ['hello']
# rlst_2
# []
# rlst_3
# ['hello', 'world']
rlst_1
已按预期更改,因为引用中的同一对象已被修改。 rlst_2
没有变化,因为即使 list_2
被重新分配了一个新列表,它也是一个在函数内创建的 local 对象,并在函数退出后丢失。
为什么 rlst_3
得到更新?您可能认为它已更新,但它实际上是一个同名的 NEW 对象。注意函数的最后一部分 returns 本地创建的 list_3
的值为 list_1 + ['world']
。因此函数调用的计算结果如下:
rlst_3 = mod_lists(rlst_1, rlst_2, rlst_3)
(local) list_1 = ['hello']
(local) list_3 = list_1 + ['world']
(local) list_3 = ['hello', 'world']
rlst_3 = list_3
rlst_3 = ['hello', 'world']
如果这仍然令人困惑,运行 一个 id(rlst_3)
,您将看到 52336840
, 正是 的对象 ID本地创建的 list_3
(同样,您可能会看到不同的数字,但 id(rlst_3)
将始终等于 id(list_3)
)。
应用这个逻辑,现在你可以理解为什么不可能在引用中传递不可变整数并希望在函数中修改它们了。您可以更改外部对象的唯一方法是将它们重新分配给函数返回的新创建的本地对象。
这个答案显然比 Stephen Rauch 的答案冗长得多,但它提供了更多的背景知识来说明为什么它不起作用。
我正在尝试从另一个名为 "File1" 的文件调用函数 passvalue
作为 "Main File" 的模块。我希望 "Main File" 中的 x
的值是 4 而不是 1,并且 y
的值在调用函数后是 3 而不是 2。
问题:我如何确保来自 "File1" 的模块函数的值被传递到 "Main File"?对于这种情况,x=4
和 y=3
.
我的想法:我尝试使用全局值,但它似乎不起作用,return 在这种情况下只会 return x
或 y
值回到函数本身,这可能会破坏目的。
感觉好像我错过了一些简单的东西,但似乎无法理解。
文件 1:
def passvalue(a,b)
b=b+a
a=b+b
主要:
import File1
x=1
y=2
File1.passvalue(x,y)
print(x)
print(y)
您需要 return
如下值:
def passvalue(a,b)
b=b+a
a=b+b
return a, b
这个returns一个tuple
. The tuple
can the unpacked喜欢:
# Main File
import File1
x=1
y=2
x, y = File1.passvalue(x,y)
print(x)
print(y)
它不起作用的原因有多种:
首先,函数中分配的对象是本地创建的。当您执行 a=...
和 b=...
时,a
和 b
是您在分配给参数的函数中创建的 local 对象值。函数退出后,a
和 b
不再与直接函数作用域外的代码保持任何相关性。
其次,当对象在 Python 中通过 引用 传递时,保持不变的是不可变的。由于 x
和 y
是整数,它们是不可改变的,即每次你对它们执行任何操作时,一个新值被 分配 给对象而不是它改变了。
要理解这一点,请考虑以下函数:
def mod_lists(list_1, list_2, list_3):
print("obj ID of rlst_1 = {0}\n"
"obj ID of rlst_2 = {1}\n"
"obj ID of rlst_3 = {2}\n".format(id(rlst_1), id(rlst_2), id(rlst_3)))
print("Before change:\n"
"obj ID of list_1 = {0}\n"
"obj ID of list_2 = {1}\n"
"obj ID of list_3 = {2}\n".format(id(list_1), id(list_2), id(list_3)))
list_1.append("hello")
list_2 = list_1 + ["world"]
list_3 = list_1 + ["world"]
print("After change:\n"
"obj ID of list_1 = {0}\n"
"obj ID of list_2 = {1}\n"
"obj ID of list_3 = {2}\n".format(id(list_1), id(list_2), id(list_3)))
return list_3
现在考虑我要传递三个 list
s:
rlst_1 = list()
rlst_2 = list()
rlst_3 = list()
我调用函数如下:
rlst_3 = mod_lists(rlst_1, rlst_2, rlst_3)
现在您可能期望 rlst_1 = ['hello']
、rlst_2 = ['hello', 'world']
和 rlst_3 = ['hello', 'world']
,但这是错误的。如果你 运行 它,你会注意到 rlst_2
实际上是一个空 list
(不变)。
那么是什么让 rlst_1
和 rlst_3
发生了变化?我们看一下打印出来的对象ID,对比一下:
# NOTE: You will see different numbers on your system.
obj ID of rlst_1 = 52178816
obj ID of rlst_2 = 52337240
obj ID of rlst_3 = 51607312
Before change:
obj ID of list_1 = 52178816
obj ID of list_2 = 52337240
obj ID of list_3 = 51607312
After change:
obj ID of list_1 = 52178816
obj ID of list_2 = 52336920
obj ID of list_3 = 52336840
在函数中进行任何更改之前,您可以看到对象 ID 分别 完全相同,这意味着 list_1
是 [= 的精确引用30=],等。现在,在完成更改后,您会注意到更改。您可以看到 list_2
和 list_3
现在具有不同的对象 ID。这是为什么?那是因为在 list_2=...
和 list_3=...
行中,您有效地 将两个对象重新分配 到一个新引用,即 list_1 + ['world']
。您可能还想知道为什么它们都有不同的 ID,因为值应该相同。虽然 list_1
是相同的引用,但每个 ['world']
都是 list
对象的 新实例 ,其中包含单词 "world"
作为项目, 所以它们是不同的对象,即使它们具有相同的值。
为什么 list_1
的对象引用没有受到影响?这是因为当您在 list_1
上调用 append
函数时,它不会 重新分配 而是更改引用中的对象,附加值 "hello"
进入同一个对象。
函数调用后,打印 rlst
时,您将看到:
# rlst_1
# ['hello']
# rlst_2
# []
# rlst_3
# ['hello', 'world']
rlst_1
已按预期更改,因为引用中的同一对象已被修改。 rlst_2
没有变化,因为即使 list_2
被重新分配了一个新列表,它也是一个在函数内创建的 local 对象,并在函数退出后丢失。
为什么 rlst_3
得到更新?您可能认为它已更新,但它实际上是一个同名的 NEW 对象。注意函数的最后一部分 returns 本地创建的 list_3
的值为 list_1 + ['world']
。因此函数调用的计算结果如下:
rlst_3 = mod_lists(rlst_1, rlst_2, rlst_3)
(local) list_1 = ['hello']
(local) list_3 = list_1 + ['world']
(local) list_3 = ['hello', 'world']
rlst_3 = list_3
rlst_3 = ['hello', 'world']
如果这仍然令人困惑,运行 一个 id(rlst_3)
,您将看到 52336840
, 正是 的对象 ID本地创建的 list_3
(同样,您可能会看到不同的数字,但 id(rlst_3)
将始终等于 id(list_3)
)。
应用这个逻辑,现在你可以理解为什么不可能在引用中传递不可变整数并希望在函数中修改它们了。您可以更改外部对象的唯一方法是将它们重新分配给函数返回的新创建的本地对象。
这个答案显然比 Stephen Rauch 的答案冗长得多,但它提供了更多的背景知识来说明为什么它不起作用。