Python 为什么可以';如果在if语句中使用外部函数的参数,我是否覆盖该参数的值?

Python 为什么可以';如果在if语句中使用外部函数的参数,我是否覆盖该参数的值?,python,scope,Python,Scope,我正在编写一个用参数初始化的装饰器,我尝试将该参数默认设置为None,然后检查该参数是否为None,如果是,则检查argument=some\u default\u值。我已经总结了我遇到的问题: 此代码有效(它打印None): def外部(arg=None): def inner(): 打印(arg) 内() 外() 此代码有效(它打印22): def外部(arg=None): def inner(): arg=22 打印(arg) 内() 外() 此代码不会: def外部(arg=None

我正在编写一个用参数初始化的装饰器,我尝试将该参数默认设置为
None
,然后检查该参数
是否为None
,如果是,则检查
argument=some\u default\u值
。我已经总结了我遇到的问题:

此代码有效(它打印
None
):

def外部(arg=None):
def inner():
打印(arg)
内()
外()
此代码有效(它打印
22
):

def外部(arg=None):
def inner():
arg=22
打印(arg)
内()
外()
此代码不会:

def外部(arg=None):
def inner():
如果arg为None:
arg=22
打印(arg)
内()
外()
我得到以下错误:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    outer()
  File "test.py", line 6, in outer
    inner()
  File "test.py", line 3, in inner
    if arg is None:
UnboundLocalError: local variable 'arg' referenced before assignment
回溯(最近一次呼叫最后一次):
文件“test.py”,第8行,在
外()
文件“test.py”,第6行,在外部
内()
文件“test.py”,第3行,在内部
如果arg为None:
UnboundLocalError:赋值前引用了局部变量“arg”

为什么在
if
语句中使用变量
arg
会使Python决定必须在该范围内而不是在外部范围内定义它?

变量的范围是在定义函数时确定的。通过分配给
arg
,可以使
arg
成为整个范围内的局部变量,这意味着
如果arg为None
则现在正在测试尚未定义的局部变量
arg
,而不是
外部
定义的非局部变量。(换句话说,函数体中存在赋值语句会使名称成为局部的,而不是语句的实际执行,这将通过该名称创建变量。)

您可以通过在
internal
的主体中将
arg
声明为非本地来修复此问题:

def outer(arg=None):
    def inner():
        nonlocal arg

        if arg is None:
            arg = 22
        print(arg)
    inner()

outer()

尽管要注意,对
arg
的更改在调用
internal
之后也是可见的,因为您更改的是
outer
的局部变量
arg

if
语句与此无关。如果作用域包含对变量的任何赋值,则该变量默认为局部变量,除非明确声明为
global
nonlocal
。在这两个示例中,都有两个名为
arg
的完全不相关的变量,一个在
outer
中,另一个在
internal
中。请尝试使用相同的方法:def-inner(arg)/inner(arg)。必须传输arg变量,因为它不是全局变量。在“inner()”中,在创建arg变量之前,没有arg变量。