我一直试图在变量中的函数中返回一个变量并在它之外使用它:
test = 0
def testing():
test = 1
return test
testing()
print(test)
但是当我运行它时,结果为 0。我该如何解决这个问题?
我一直试图在变量中的函数中返回一个变量并在它之外使用它:
test = 0
def testing():
test = 1
return test
testing()
print(test)
但是当我运行它时,结果为 0。我该如何解决这个问题?
你搞砸了范围和/或分配。尝试这个:
def testing():
test = 1
return test
test = testing()
print(test)
说明:test
内部与模块内部testing
不同。test
您必须在模块级别分配它才能获得预期的结果。
因为您test
在函数中声明,它不是全局变量,因此,您无法访问test
您在函数外部创建的变量,因为它们是不同的范围
如果你想要return test
一个变量,你必须这样做
result = testing()
print(result)
或者,您还可以添加一条global
语句:
test = 0
def testing():
global test
test = 1
return test
testing()
print(test)
顺便说一句,在执行条件语句时,您不需要1==1
:) 周围的括号。
在函数内部testing()
,您正在创建一个新变量test
,而不是指已经存在的变量。如果你想这样做,你应该global
在顶部使用一个语句,如下所示:
def testing():
global test
...etc...
函数内的test
变量没有全局范围。因此,如果您想将返回值存储在变量中并在此之后输出,您可以执行以下操作:
result = testing()
print(result)
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
外部范围和外部范围中,但它并不指代同一事物。这有两个重要的含义:
test
不会影响外部 test
。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)
附录:函数可以修改其包含范围。但是,必须将名称显式声明为来自外部范围。
nonlocal
andglobal
关键字允许从外部范围修改名称。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
请注意,修改外部名称通常是反模式的标志,global
s 比nonlocal
s 更是如此。除了小脚本之外,很难追踪访问和修改global
s 的内容。通常,使用类或生成器来保存状态更合适。
一个函数总是可以从其包含范围中读取名称,前提是它永远不会写入相同的名称。这样的闭包很容易创建,而且不需要修改也更容易追踪。请注意,在函数中的任何位置修改名称都会使其成为本地名称,除非声明global
或nonlocal
:
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