【问题标题】:Python3 variable passing issuePython3变量传递问题
【发布时间】:2019-05-08 12:07:04
【问题描述】:

示例代码,尽量忽略它看起来不必要地过于复杂 - 这是从实际代码中简化的方式,但完全模仿了流程。

def setup():
   print("Setting up...")
   do_something()

def do_something():
   task = str(input("Enter a task to do: "))
   try:
      print("Doing {}...".format(task))
   except:
      print("Failed to do {}...".format(task))
   finally:
      return task

def choose_2(choice):
   print("You chose {}".format(choice))

def menu_1():
   choice = int(input("Choose 1 or 2: "))
   if choice == 1:
      setup()
      menu_2(task)

menu_1()

但是,程序返回“UnboundLocalError: local variable 'task' referenced before assignment

为什么do_something()将变量task返回到if内的if语句?一旦setup()(以及随后的do_something())完成运行,do_something() 的返回值不应该保留在if 语句中,因为它还没有完成吗?

【问题讨论】:

  • 是的,您只需丢弃它。 return 除了 return 一个值,而不是来自函数的 variable 之外什么都不做。 menu_1 中没有定义 task 变量
  • @juanpa.arrivillaga 所以 return 返回的是'task'变量的,而不是'task'变量本身?
  • 是的。变量对于函数来说是local,或者可以在全局范围内,或者在某个封闭范围内。你不传递变量,你传递值。变量通常只存在于给定的函数执行。所以返回一些东西的函数通常期望你在调用者中捕获那个值,所以returned_value = some_func(),如果some_func返回foo并不重要,因为foo不会在你调用some_func的地方定义, 除非做类似foo = some_func的事情,但它们仍然是两个不同的变量
  • 您需要捕获从函数返回的值以对这些值执行某些操作,否则它们将变得无法访问,并且如果不存在其他引用,它们将被垃圾收集。每次调用返回值的函数时,都需要在调用者的变量中捕获该值。就像您使用任何内置函数一样,例如你会x = input(...) 对吗?你为什么不直接做input()
  • @juanpa.arrivillaga 因为这是我的问题的真正答案,你可以把它放在一个答案中,如果你愿意,我会标记它。

标签: python python-3.x variables return try-catch


【解决方案1】:

流程是: menu_1() => menu_2(task)

task没有定义在menu_1()的范围内,所以无法定义。

您可能本来打算这样做:

def setup():
   print("Setting up...")
   return do_something()
.....
# in menu_1():
menu_2(setup())

请注意,因为setup 现在返回一些东西,所以它可以使用该返回值。

【讨论】:

  • 他们在menu_1中调用setup,它调用do_something,它返回task。当然,setup 不会返回任何内容,但是 OP 对 return 的作用和变量范围存在根本性的误解
  • 这也解决不了问题。问题是他们认为return 会神奇地将变量 插入到调用者范围内。
  • 是的@juanpa.arrivillaga 是对的——我误解了“return”的作用。我想我只需要重新考虑我的整体逻辑/流程......
  • 您认为他们只需要了解global 关键字的工作原理吗?
  • @JacobIRR 没有。 global 是一种糟糕的做法
【解决方案2】:

setup() 和 menu_1() 函数应该这样改变:

def setup():
    print("Setting up...")
    do_something()

def menu_1():
   choice = int(input("Choose 1 or 2: "))
   if choice == 1:
       task=setup()
       menu_2(task)

说明: menu_1() 调用 setup(),setup() 调用 do_something()。现在 'do_something()' 将返回 task 的值,但您不会将它从 'setup()' 函数返回到 menu_1(),然后在 menu_1() 中,您必须将返回的值存储在名为 'task' 的变量中。

【讨论】:

  • 'return task' 将返回任务的值,您必须将其存储在调用函数中的某个位置(setup())或将该值返回给堆栈中存在的下一个函数,即' menu_1()'
猜你喜欢
  • 2019-12-19
  • 2022-01-24
  • 2014-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多