简体   繁体   English

在使用None将默认参数设置为Python中的函数时,为什么会出现“ UnboundLocalError”?

[英]When setting default arguments to a function in Python using None, why I am getting 'UnboundLocalError'?

In the following function ,clc, whenever I fail to pass the third argument 'z', I want the fuction to automatically perform addition. 在以下函数,clc中,每当我未能传递第三个参数'z'时,我都希望功能自动执行加法。 (ie) If I pass only two arguments (150,200), I want to get the same result as I do when I pass (150,200,'a'). (即)如果我仅传递两个参数(150,200),则希望获得与传递(150,200,'a')时相同的结果。 Unfortunately I am getting a traceback that 'UnboundLocalError: local variable 'r' referenced before assignment'. 不幸的是,我得到的回溯是“ UnboundLocalError:分配前引用了本地变量” r”。 Can anyone please explain why I get this error? 谁能解释为什么我会收到此错误? Thanks. 谢谢。

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

Edit: Thanks to PM2Ring for his explanation which cleared my error! 编辑:感谢PM2Ring的解释,它清除了我的错误! This is his reply : 'If you just hit Enter at the 'enter the operation' prompt then op gets assigned the empty string '', it's not None. 这是他的回答:“如果只是在“输入操作”提示下按Enter,然后op被分配了空字符串”,那么它不是None。 And then when you call clc(a,b,op) none of your if tests are True, and so r never gets assigned a value. 然后,当您调用clc(a,b,op)时,您的if测试都不为True,因此r永远不会被赋值。 The if statement I posted earlier handles that empty string case.' 我之前发布的if语句处理了空字符串的情况。

Something tells me your input to op does not fit the bill for any of those if statements to get triggered, resulting in r never being defined or returned. 某件事告诉我,对于任何if语句要触发,您对op的输入都不符合要求,从而导致r从未被定义或返回。 One option would be to declare r = None outside the conditional block, so you get rid of that error. 一种选择是在条件块之外声明r = None ,因此您可以摆脱该错误。

However, if you're working with simple arithmetic operations (involving two operands only), I'd recommend keeping a dictionary of operations, and then invoking the correct one as needed. 但是,如果您使用简单的算术运算(仅涉及两个操作数),建议您保留一本运算字典,然后根据需要调用正确的运算字典。

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)

As an aside, as PM 2Ring remarked , if you want the default argument to come into play, don't pass anything to op . 顺便说一句 ,正如PM 2Ring所说 ,如果要使用默认参数,则不要将任何内容传递给op


Unfortunately, if you're looking to penalising invalid inputs, the function above needs modification, because it is highly tolerant to all invalid/missing inputs, defaulting to addition in each case. 不幸的是,如果您要惩罚无效的输入,则需要对上述函数进行修改,因为它对所有无效/缺失的输入具有很高的容忍度,在每种情况下都默认添加。 You can make a small change to get this to work, however, using the EAFP approach with exception handling. 您可以稍作更改以使其正常工作,但是,请使用带有异常处理的EAFP方法。

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

The issue is the line op=input('enter the operation:\\t') . 问题是行op=input('enter the operation:\\t') If you enter nothing, it still returns '' , an empty string, so for the z argument, you pass in '' . 如果不输入任何内容,它仍将返回'' (空字符串),因此对于z参数,您传入'' The interpreter runs through all of your if and elif statements, and none of them are satisfied, so it just returns r . 解释器遍历所有ifelif语句,但都不满足,因此只返回r However, r has not been assigned any value, so an exception is raised. 但是,尚未为r分配任何值,因此引发了异常。

Instead, you should write something like this 相反,您应该编写这样的内容

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我在 function 下面出现 unboundLocalError? - Why I am getting unboundLocalError in below function? 为什么我收到unboundLocalError? - Why am I getting an unboundLocalError? 为什么在我的Python脚本的except子句中出现UnboundLocalError? - Why am I getting an UnboundLocalError in the except clause of my Python script? 为什么我在这段代码中收到“UnboundLocalError”? - Why am I getting “UnboundLocalError” in this code? 为什么我在 Flask 中收到 UnboundLocalError? - Why i am getting UnboundLocalError in Flask? 为什么在Python中赋值之前会收到UnboundLocalError消息,该消息指出局部变量“参与者”被引用? - Why am I getting the UnboundLocalError that says local variable 'participants' referenced before assignment in Python? 为什么在尝试分配变量时出现UnboundLocalError? - Why am I getting an UnboundLocalError while trying to assign a variable? 无法弄清楚为什么我收到UnboundLocalError - Cannot figure out why I am getting UnboundLocalError 为什么在python函数中使用.map会出错 - Why am I getting error using .map in python function 使用Scipy.optimization的蛮干功能时,为什么会出现“ ValueError:设置具有序列的数组元素”的问题? - Why am I getting “ValueError: setting an array element with a sequence.” when using the brute function from Scipy.optimization?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM