1

我一直试图在变量中的函数中返回一个变量并在它之外使用它:

test = 0

def testing():
    test = 1
    return test

testing()
print(test)

但是当我运行它时,结果为 0。我该如何解决这个问题?

4

5 回答 5

9

你搞砸了范围和/或分配。尝试这个:

def testing():
    test = 1
    return test

test = testing()
print(test)

说明:test内部与模块内部testing不同。test您必须在模块级别分配它才能获得预期的结果。

于 2013-08-04T03:45:08.013 回答
2

因为您test在函数中声明,它不是全局变量,因此,您无法访问test您在函数外部创建的变量,因为它们是不同的范围

如果你想要return test一个变量,你必须这样做

result = testing()
print(result)

或者,您还可以添加一条global语句:

test = 0

def testing():
    global test
    test = 1
    return test

testing()
print(test)

顺便说一句,在执行条件语句时,您不需要1==1:) 周围的括号。

于 2013-08-04T03:46:12.063 回答
1

在函数内部testing(),您正在创建一个新变量test而不是指已经存在的变量。如果你想这样做,你应该global在顶部使用一个语句,如下所示:

def testing():
    global test
    ...etc...
于 2013-08-04T03:47:31.207 回答
1

函数内的test变量没有全局范围。因此,如果您想将返回值存储在变量中并在此之后输出,您可以执行以下操作:

result = testing()
print(result)
于 2013-08-04T03:48:05.797 回答
0

TLDR:return必须在调用站点为某事分配一个值。

test = testing()

Python 中的函数有自己的作用域。它在进入(调用)函数时创建,并在离开时销毁。分配给范围内的名称会使该名称成为该范围的本地名称 - 导致它与范围一起被销毁。

# start outer scope
test = 0  # create name outer:test

def testing():
    # start inner scope
    test = 1  # create name outer.testing:test
    return test
    # end inner scope
    # destroy name outer.testing:test

testing()  # new temporary inner scope outer.testing
print(test)  # use name outer:test
# end outer scope

值得注意的是,内部范围内的名称可能会“遮蔽”外部范围内的名称。虽然名称test同时存在于testing外部范围和外部范围中,但它并不指代同一事物。这有两个重要的含义:

  1. 对内部 的分配test不会影响外部 test
  2. 结束时testing内部 test被破坏,只剩下外部 test

这就是调用testing()没有达到预期效果的原因:它从不修改test传递给的外部print


return语句定义调用函数返回的值。它不返回名称,只返回指向的值。

def testing():
    test = 1  # test refers to the value 1
    return test  # return test => value 1

函数返回的值与任何其他值一样 - 无论是来自文字、查找还是其他。最重要的是,除非您将其分配给名称或直接使用它,否则该值不会持续存在。

testing()  # call test, discard its value
test = testing()  # call test, store its value as `test`
print(testing())  # call test, use its value in `print`

因此,为了从函数中返回某些内容以供以后使用,您必须将结果存储到名称中。然后,您可以在以后的语句中使用该名称。您的案例的一个最小示例如下所示:

# we already can define testing here
# it is overwritten later on, then

def testing():
    # all names we use inside of testing are gone at the end
    # if we just want a value, we can skip temporary names
    return 1

# store the return value of testing() for later use
test = testing()
print(test)

附录:函数可以修改其包含范围。但是,必须将名称显式声明为来自外部范围。

nonlocalandglobal关键字允许从外部范围修改名称。Anonlocal是最接近匹配函数范围内的名称。Aglobal是模块范围内的名称,与中间的任何函数无关。

test = 0

def increment():
    global test  # declare test as belonging to a specific scope
    test += 1
    # no need to return something
    # we already modified the outer `test`

print(test)  # 0
increment()
print(test)  # 1

请注意,修改外部名称通常是反模式的标志,globals 比nonlocals 更是如此。除了小脚本之外,很难追踪访问和修改globals 的内容。通常,使用类或生成器来保存状态更合适。

一个函数总是可以从其包含范围中读取名称,前提是它永远不会写入相同的名称。这样的闭包很容易创建,而且不需要修改也更容易追踪。请注意,在函数中的任何位置修改名称都会使其成为本地名称,除非声明globalnonlocal

test = 0

def increment():
    global test
    test += 1

def show_test():
    # we never modify `test`, so it is fetched from the outside
    print(test)

def show_and_increment1():  # this function is broken!
    print(test)  # `test` is *not* the outer one, since we modify it in the function
    test += 1  # modifying `test` makes it local for the *entire* function

def show_and_increment2():  # this function works!
    global test  # force `test` to be global
    print(test)
    test += 1

show_test()  # 0
increment()
show_test()  # 1
show_and_increment2()  # 1
show_and_increment2()  # 2
show_and_increment2()  # 3
show_test()  # 4
show_and_increment1()  # UnboundLocalError: local variable 'test' referenced before assignment
于 2019-02-28T08:48:52.580 回答