使用None在Python中为函数设置默认参数时,为什么我会收到'UnboundLocalError'?

时间:2017-10-21 12:51:19

标签: python python-3.x function

在下面的函数clc中,每当我无法传递第三个参数'z'时,我希望函数自动执行加法。 (即)如果我只通过两个  参数(150,200),我希望得到与我通过时相同的结果(150,200,'a')。不幸的是,我得到一个追溯'UnboundLocalError:局部变量'r'在赋值之前被引用'。任何人都可以解释为什么我会收到此错误?感谢。

def clc(x,y,z=None):
    if (z=='a') or (z is None):
        r=x+y
    elif z=='s':
        r=x-y
    elif z=='m':
        r=x*y
    elif z=='d':
        r=x/y
    elif z=='mod':
        r=x%y
    elif z=='ex':
        r=x**y
    return r
while True:
    a=int(input('Enter a number:\t '))
    b=int(input('Enter a number:\t '))
    op=input('enter the operation:\t')
    answer=clc(a,b,op)
    print('the answer is',answer)
    query=input('If you want to continue, please press Enter\t')
    if len(query)>0:
        break

编辑:感谢PM2Ring的解释清除了我的错误!这是他的答复:'如果你只是在'输入操作'提示符下按Enter键,那么op将被赋予空字符串'',它不是None。然后当你调用clc(a,b,op)时,你的if测试都不是True,所以r永远不会被赋值。我之前发布的if语句处理空字符串case。

2 个答案:

答案 0 :(得分:0)

有些东西告诉我你对op的输入不符合任何这些if语句被触发的账单,导致永远不会定义或返回r。一种选择是在条件块之外声明r = None,这样你就可以摆脱那个错误。

但是,如果你正在使用简单的算术运算(仅涉及两个操作数),我建议保留一个操作字典,然后根据需要调用正确的算法。

import operator

_f = {'a' : operator.add, 's' : operator.sub, 'm' : operator.mul, 'd' : operator.div} 
def clc(x, y, op=None):
    return _f.get(op, operator.add)(x, y)

另外,作为PM 2Ring remarked,如果您希望默认参数发挥作用,请不要将任何内容传递给op

不幸的是,如果你正在寻找惩罚无效输入,那么上面的函数需要修改,因为它对所有无效/丢失的输入都是高度容忍的,在每种情况下都默认为添加。但是,您可以使用 EAFP 方法进行异常处理,从而进行一些小改动以使其正常工作。

_f.update({None : operator.add})
def clc(x, y, op=None):
    try:
       return _f[op](x, y)
    except KeyError:
        return "Invalid Operation"

答案 1 :(得分:-1)

问题是行op=input('enter the operation:\t')。如果您什么都不输入,它仍会返回'',一个空字符串,因此对于z参数,您传入''。解释器会遍历您的所有ifelif语句,并且都不会满足,因此只返回r。但是,r尚未分配任何值,因此会引发异常。

相反,你应该写这样的东西

def clc(x,y,z):
    if z=='a' or z=='':
        r=x+y
    elif z=='s':
        r=x-y
    elif z=='m':
        r=x*y
    elif z=='d':
        r=x/y
    elif z=='mod':
        r=x%y
    elif z=='ex':
        r=x**y
    else:
        return 'N/A'
    return r
while True:
    a=int(input('Enter a number:\t '))
    b=int(input('Enter a number:\t '))
    op=input('enter the operation:\t')
    answer=clc(a,b,op)
    print('the answer is',answer)
    query=input('If you want to continue, please press Enter\t')
    if len(query)>0:
        break