当我尝试向函数添加一条简单的错误消息时,我的项目变得越来越大了,有一天我遇到了这个问题:
def create_report(id):
report = new_report(id)
if not report:
raise api_error('Could not find report with id %d' % (id,))
...
问题? id
是一个字符串,它在尝试将其格式化为数字时崩溃了。我不是该函数的原始作者,错误地认为id
将是一个数字。相反它应该是一个字符串。糟糕。
如果这是一种强类型语言,我会立即从编译器中得到错误;这些事情最好的方法是什么?我应该检查每个参数的类型(看起来像很多腿部工作),还是应该把所有参数放在try:
块中?也许我们应该在描述它的参数的每个函数中写一个注释?或者我本来应该知道更好?
答案 0 :(得分:2)
该格式字符串应该使用%s
,而不是因为id
是字符串,但因为它通常是最佳选择。 %d
需要数字类型,但如果需要,%s
会将其他类型转换为字符串。只有在需要更改数字格式时才应使用%d
。
答案 1 :(得分:0)
使参数类型更加健壮的可能策略是写:
def create_report(id):
report = new_report(id)
if not report:
raise api_error('Could not find report with id %s' % (id,))
...
它看起来并不总是很好,但至少它不会轻易破坏。
但总的来说,与函数签订一些明确的合同总是更好。 docstring是正确的地方。
答案 2 :(得分:0)
如果你真的想确保字符串打印功能不会崩溃,你可能最好使用%s,它使用pythons str() - function将积分值转换为字符串。 看看你正在谈论它是一个ID,我会假设它是int类型 - 在这种情况下这个解决方案应该可以正常工作(如果你使用浮点数,我不太确定有多少个数字str()将继续)。
修改的 噢,小伙子,我很慢......
答案 3 :(得分:0)
尝试使用%s然后使用str(变量)。这将确保所有内容都转换为字符串(甚至列表和元组)并且不会发生TypeError
def create_report(id):
report = new_report(id)
if not report:
raise api_error('Could not find report with id %s' % (str(id),))
...
答案 4 :(得分:0)
甚至比其他答案'%s
更好,我发现使用%r
是最好的,如果该消息是供开发人员使用的话。这有助于您区分细微的案例。例如,如果使用'12 '
为id调用此函数,则%s消息将不显示尾随空格。 %r
使用值的repr(),因此将包含引号,帮助您查看精确值。
答案 5 :(得分:0)
我认为这里的问题是你断言某些代码中的值,当发生意外事件时应该执行该代码。也许更好的方法是更改new_report(id)
以在出现问题时引发异常 - 指定它是否为值错误或无法找到id。然后你的代码应该是:
def create_report(id):
report = new_report(id)
...
def new_report(id):
try:
# find the report by id
# if couldn't find raise api_error
except ValueError:
# explain that id is the wrong type