从模块中传递来自调用函数的值(Python)

时间:2018-02-07 02:55:48

标签: python function python-module

我试图从另一个名为" File1"的文件中调用函数passvalue。作为"主文件"的模块。我期望{"主文件"中x的值在调用函数后,为4而不是1,y的值为3而不是2。

问题:如何确保模块的功能来自" File1"被传递到"主文件"?在这种情况下,x=4y=3

我的想法:我尝试使用全局值,但它似乎不起作用,在这种情况下返回只会返回函数本身的xy值,这可能会打败目的。

感觉我错过了一些简单的东西,但似乎无法得到它。

File1中:

def passvalue(a,b)
  b=b+a
  a=b+b

import File1
x=1
y=2
File1.passvalue(x,y)
print(x)
print(y)

2 个答案:

答案 0 :(得分:2)

您需要return这样的值:

def passvalue(a,b)
    b=b+a
    a=b+b
    return a, b

这会返回tupletuple # Main File import File1 x=1 y=2 x, y = File1.passvalue(x,y) print(x) print(y) 可以像JSON_UNQUOTE一样:

select JSON_UNQUOTE(JSON_EXTRACT(base, '$.scope')) as scope from t_name

答案 1 :(得分:1)

它有多种原因不起作用:

首先,在本地中创建函数中分配的对象。当您执行a=...b=...时,ab是您在分配给参数值的函数中创建的本地对象。函数退出后,ab不再与直接函数范围之外的代码保持任何相关性。

其次,虽然对象在Python中的引用中传递,但仍然是不可变的是不可变的。由于xy是整数,因此它们是不可变的,即每次对它们执行任何操作时,都会向对象分配而不是它改变。

要理解这一点,请考虑以下功能:

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

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_1rlst_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_1rlst_1的精确引用,等等现在,在完成更改后,您会注意到更改。您可以看到list_2list_3现在具有不同的对象ID。这是为什么?这是因为在行list_2=...list_3=...中,您实际上将两个对象重新分配到新引用,即list_1 + ['world']。您可能也想知道为什么它们都有不同的ID,因为值应该相同。虽然list_1是相同的引用,但每个['world']都是list对象的新实例,其中包含单词"world"作为项目,因此它们是即使它们具有相同的值,它们也是不同的对象。

为什么list_1的对象引用不受影响?这是因为当您在append上调用list_1函数时,它不会重新分配,而是更改引用中的对象,将值"hello"附加到其中对象

现在,在函数调用之后,当您打印rlst时,您将看到:

# rlst_1
# ['hello']
# rlst_2
# []
# rlst_3
# ['hello', 'world']
正如所料,

rlst_1已更改,因为修改了引用中的同一对象。 rlst_2未更改,因为即使list_2重新分配了新列表,它也是在函数内创建的 local 对象,并在函数退出后丢失。

为什么rlst_3会更新?您可能认为它已更新,但它实际上是一个具有相同名称的 NEW 对象。注意函数的最后一部分返回本地创建的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正好本地创建的list_3的对象ID(再次,您可能会看到不同的数字,但id(rlst_3)将始终等于id(list_3)。)

应用这个逻辑,现在你可以理解为什么不可能在引用中传递不可变整数并希望在函数中修改它们。更改外部对象的唯一方法是将它们重新分配给函数返回的新创建的本地对象。

这个答案显然比斯蒂芬劳赫的答案长得多,但它给出了更多的背景知识,为什么它不起作用。