在 Pythonese 中怎么说 - 做某事除非它导致错误(不求助于多级 try/execpt 块)
How to say in Pythonese - do something unless it causes an error (without resorting to multilevel try/execpt blocks)
这有点难以解释,所以希望我能连贯地表达问题:
假设我有这个列表:
my_list = ["a string", 45, 0.5]
要了解问题的关键点是 my_list
是由另一个函数生成的;我事先不知道有关 my_list
的任何信息,特别是它的长度和它的任何成员的数据类型。
接下来说每次生成<my_list>
,都有一些我要对它进行的预定操作。例如,我想:
my_text = my_list[1]+"hello"
some_var = my_list[10]
mini_list = my_list[0].split('s')[1]
my_sum = my_list[7]+2
等这里重要的一点是,它是大量的操作。
显然,其中一些操作会在任何给定的 my_list
下成功,而有些会失败,重要的是,那些失败的操作将以不可预测的 Error 类型进行;但我需要 运行 在每一代 my_list
.
上全部
一个明显的解决方案是对每个操作使用 try/except:
try:
my_text = my_list[1]+"hello"
except:
my_text = "None"
try:
some_var = my_list[10]
except:
some_var = "couldn't do it"
等等
但是操作量大的话,会很麻烦。我调查了关于多个 try/except 的各种问题,但除非我遗漏了什么,否则他们不会解决这个问题。
根据某人的建议(抱歉,丢失了 link),我尝试创建一个内置函数 try/except,创建另一个这些操作的列表,并将每个操作发送到功能。类似于
def careful(op):
try:
return op
else:
return "None"
并将其与第一个操作一起使用:
my_text = careful(my_list[1]+"hello")
问题是 python 似乎评估 careful()
参数 之前 它被发送到函数并且在它被捕获之前生成错误...
所以我想我正在寻找一种可以执行类似操作的三元运算符形式:
my text = my_list[1]+"hello" if (this doesn't cause any type of error) else "None"
但是,即使存在,我也找不到...
任何想法都将受到欢迎,对于冗长的post感到抱歉。
也许是这样的?
def careful(op, default):
ret = default
try:
ret = computation()
else:
pass
return ret
这听起来像 XY Problem
如果您可以更改源逻辑,返回 dict
可能是更好的解决方案。然后您可以在执行某些操作之前确定键是否存在,并且还可以查找如果键存在于另一个 dict
.
中应该执行的操作
如果您必须这样做,请考虑将操作集合保存为字符串并在循环中对它们调用exec
actions = [
'my_text = my_list[1]+"hello"',
'some_var = my_list[10]',
'mini_list = my_list[0].split("s")[1]',
'my_sum = my_list[7]+2',
]
如果您将此合集设置为 dict
,您还可以指定一个默认值
请注意,如果默认操作(或操作字符串的一部分)是字符串,则必须将其引用两次。如果您已经进行了复杂的转义,请考虑为此使用块引号,例如返回原始字符串或表示正则表达式的字符串
{
"foo = bar": r"""r'[\w]+baz.*'"""
}
完整示例:
>>> actions_defaults = {
... 'my_text = my_list[1]+"hello"': '"None"',
... 'some_var = my_list[10]': '"couldn\'t do it"',
... 'mini_list = my_list[0].split("s")[1]': '"None"',
... 'my_sum = my_list[7]+2': '"None"',
... }
>>>
>>> for action, default in actions_defaults.items():
... try:
... exec(action)
... except Exception: # consider logging error
... exec("{} = {}".format(action.split("=")[0], default))
...
>>> my_text
'None'
>>> some_var
"couldn't do it"
其他说明
- 这很邪恶
- 在 运行 之前声明你的变量是它们的默认值可能是 better/clearer (足以
except
块中的 pass
,因为分配将失败)
- 您可能 运行 进入奇怪的范围并且需要通过
locals()
访问一些变量
这有点难以解释,所以希望我能连贯地表达问题:
假设我有这个列表:
my_list = ["a string", 45, 0.5]
要了解问题的关键点是 my_list
是由另一个函数生成的;我事先不知道有关 my_list
的任何信息,特别是它的长度和它的任何成员的数据类型。
接下来说每次生成<my_list>
,都有一些我要对它进行的预定操作。例如,我想:
my_text = my_list[1]+"hello"
some_var = my_list[10]
mini_list = my_list[0].split('s')[1]
my_sum = my_list[7]+2
等这里重要的一点是,它是大量的操作。
显然,其中一些操作会在任何给定的 my_list
下成功,而有些会失败,重要的是,那些失败的操作将以不可预测的 Error 类型进行;但我需要 运行 在每一代 my_list
.
一个明显的解决方案是对每个操作使用 try/except:
try:
my_text = my_list[1]+"hello"
except:
my_text = "None"
try:
some_var = my_list[10]
except:
some_var = "couldn't do it"
等等
但是操作量大的话,会很麻烦。我调查了关于多个 try/except 的各种问题,但除非我遗漏了什么,否则他们不会解决这个问题。
根据某人的建议(抱歉,丢失了 link),我尝试创建一个内置函数 try/except,创建另一个这些操作的列表,并将每个操作发送到功能。类似于
def careful(op):
try:
return op
else:
return "None"
并将其与第一个操作一起使用:
my_text = careful(my_list[1]+"hello")
问题是 python 似乎评估 careful()
参数 之前 它被发送到函数并且在它被捕获之前生成错误...
所以我想我正在寻找一种可以执行类似操作的三元运算符形式:
my text = my_list[1]+"hello" if (this doesn't cause any type of error) else "None"
但是,即使存在,我也找不到...
任何想法都将受到欢迎,对于冗长的post感到抱歉。
也许是这样的?
def careful(op, default):
ret = default
try:
ret = computation()
else:
pass
return ret
这听起来像 XY Problem
如果您可以更改源逻辑,返回 dict
可能是更好的解决方案。然后您可以在执行某些操作之前确定键是否存在,并且还可以查找如果键存在于另一个 dict
.
如果您必须这样做,请考虑将操作集合保存为字符串并在循环中对它们调用exec
actions = [
'my_text = my_list[1]+"hello"',
'some_var = my_list[10]',
'mini_list = my_list[0].split("s")[1]',
'my_sum = my_list[7]+2',
]
如果您将此合集设置为 dict
,您还可以指定一个默认值
请注意,如果默认操作(或操作字符串的一部分)是字符串,则必须将其引用两次。如果您已经进行了复杂的转义,请考虑为此使用块引号,例如返回原始字符串或表示正则表达式的字符串
{
"foo = bar": r"""r'[\w]+baz.*'"""
}
完整示例:
>>> actions_defaults = {
... 'my_text = my_list[1]+"hello"': '"None"',
... 'some_var = my_list[10]': '"couldn\'t do it"',
... 'mini_list = my_list[0].split("s")[1]': '"None"',
... 'my_sum = my_list[7]+2': '"None"',
... }
>>>
>>> for action, default in actions_defaults.items():
... try:
... exec(action)
... except Exception: # consider logging error
... exec("{} = {}".format(action.split("=")[0], default))
...
>>> my_text
'None'
>>> some_var
"couldn't do it"
其他说明
- 这很邪恶
- 在 运行 之前声明你的变量是它们的默认值可能是 better/clearer (足以
except
块中的pass
,因为分配将失败) - 您可能 运行 进入奇怪的范围并且需要通过
locals()
访问一些变量