Python助手函数作用域

Python助手函数作用域,python,function,scope,local-variables,Python,Function,Scope,Local Variables,所以,我做了一大堆基本上相同的事情,只是输入有一点变化。每次都用不同的参数调用函数,对吗 显然,python认为我错了 这是我的问题的一个简化版本 def main(): x = 10 def helper(n): if (x > n): x -= n helper函数中还有很多其他的行,它在main中被调用了很多次,但是这些行导致了这个问题。我知道helper函数使用的是局部作用域,而不是main中的作用域,但我的问题是,为什么?我该如

所以,我做了一大堆基本上相同的事情,只是输入有一点变化。每次都用不同的参数调用函数,对吗

显然,python认为我错了

这是我的问题的一个简化版本

def main():
    x = 10

    def helper(n):
      if (x > n):
          x -= n
helper函数中还有很多其他的行,它在main中被调用了很多次,但是这些行导致了这个问题。我知道helper函数使用的是局部作用域,而不是main中的作用域,但我的问题是,为什么?我该如何修复它

我不想让x成为全局的,我只想让助手使用已经存在的x,而不是构建自己的x。如果没有这个辅助函数,代码行的总数至少将增加四倍,代码将是一个复杂的、无法读取的混乱


编辑:另外,Main使用了大量x,因此我不能只在本地定义它,以防不清楚。

在Python3中,可以通过将
非本地x
放在内部函数中来实现。在Python2中,您不能这样做

但是,您可以做的是从helper函数返回值,并在调用helper函数的位置分配该值。从您的示例中很难判断,但我假设您使用的是这样的示例:

def main():
    x = 10

    def helper(n):
        if (x > n):
            x -= n

    # do something that changes x
    helper(2)
    # now x has changed
相反,请执行以下操作:

def helper(x, n):
    if (x > n):
        return x - n
    else:
        return x

def main():
    x = 10

    # do something that changes x
    x = helper(x, 2)
    # now x has changed

其思想是将所需的值传递给helper函数,并让它返回结果值,然后您可以在调用helper的位置分配(或执行您喜欢的操作)。这通常也使代码更容易理解,而不是让helper函数直接修改其调用者中的变量。还请注意,这里您可以在
main
外部定义
helper
,在两者之间创建一个更清晰的分隔,并使
helper
可用于其他函数。

在Python 3中,您可以通过将
非局部x
放在内部函数中来实现这一点。在Python2中,您不能这样做

但是,您可以做的是从helper函数返回值,并在调用helper函数的位置分配该值。从您的示例中很难判断,但我假设您使用的是这样的示例:

def main():
    x = 10

    def helper(n):
        if (x > n):
            x -= n

    # do something that changes x
    helper(2)
    # now x has changed
相反,请执行以下操作:

def helper(x, n):
    if (x > n):
        return x - n
    else:
        return x

def main():
    x = 10

    # do something that changes x
    x = helper(x, 2)
    # now x has changed

其思想是将所需的值传递给helper函数,并让它返回结果值,然后您可以在调用helper的位置分配(或执行您喜欢的操作)。这通常也使代码更容易理解,而不是让helper函数直接修改其调用者中的变量。还请注意,这里您可以在
main
外部定义
helper
,在两者之间创建更清晰的分隔,并使
helper
可用于其他功能。

问题在于:
x-=n
。由于您正在执行增广赋值,python(错误地)认为
x
是一个局部变量。不幸的是,
x
是一个“非局部”变量。在python3.x上,如果您可以在
main
范围内修改
x
,那么您可以使用
非本地
关键字。但是,我猜您不想在
main
的范围内修改
x
。一个跨版本的技巧是让自己得到一个与非本地版本具有相同值的本地变量:

def main():
    x = 10
    def helper(n):
        lx = x
        if x > n:
           lx -= n
        # etc., etc.

    helper(12)  # ...

如果您真的想在主< <代码>的范围内改变<代码> x <代码>,您可能需要考虑一个类(带有<代码>帮助器< /Cl>类中的一个方法):


问题就在这行:
x-=n
。由于您正在执行增广赋值,python(错误地)认为
x
是一个局部变量。不幸的是,
x
是一个“非局部”变量。在python3.x上,如果您可以在
main
范围内修改
x
,那么您可以使用
非本地
关键字。但是,我猜您不想在
main
的范围内修改
x
。一个跨版本的技巧是让自己得到一个与非本地版本具有相同值的本地变量:

def main():
    x = 10
    def helper(n):
        lx = x
        if x > n:
           lx -= n
        # etc., etc.

    helper(12)  # ...

如果您真的想在主< <代码>的范围内改变<代码> x <代码>,您可能需要考虑一个类(带有<代码>帮助器< /Cl>类中的一个方法):


你有例外吗
UnboundLocalError
也许?您可以简单地将
x
作为参数发送到
helper()
…@alfasin--可能。这实际上取决于OP对
x
的期望值(例如,期望x在函数内部发生变异,但传递一个不可变的对象…)是否出现异常
UnboundLocalError
也许?您可以简单地将
x
作为参数发送到
helper()
…@alfasin--可能。这实际上取决于OP对
x
的期望值(例如,期望x在函数内部发生变异,但传递一个不可变的对象…)从问题中的示例很难判断,但我认为这不会满足OP的要求,因为我认为OP试图使用helper来实际修改外部函数中的
x
。在
helper
中创建一个新的局部变量将允许您修改该新变量,但它不会“帮助”,因为它不会影响
main
@BrenBarn中的
x
——是的,很难说。我已经用另一种方法更新了。这几乎有效。它没有给出错误并且运行正常,但是它没有在以后将
lx
值传递回main。@MatthewFournier--Ahh,所以您确实想在
main
中对
x
进行变异。在这种情况下,您需要从
helper
返回它,并重新绑定它,例如
x=helper(n)
,或者使用基于类的方法(这可能比它值得的麻烦多)。@mgilson——问题是,有一些helper修改了多个变量。很难从t中的示例中分辨出来