要检查方法是否被正确调用,我想检查每个字符并使程序员不可能错误地使用该方法。因为该方法将在Web服务器中以return redirect(...)
的形式调用,所以我想引发一个异常,而不是返回错误值(例如False
或None
)。
def redirect(uri):
[raise ValueError('URI must be URL-encoded, ASCII only!') for c in uri if not (32 <= ord(c) <= 127)]
这给出了“无效语法”例外:
File "server.py", line 115
[raise ValueError('URI must be URL-encoded, ASCII only!') for c in uri if not (32 <= ord(c) <= 127)]
^
SyntaxError: invalid syntax
我可以通过多种方式解决此问题,但我想知道:为什么不允许在列表理解中进行举报?
答案 0 :(得分:1)
从语法角度来看,您的答案在full grammar spec中。
$result = Model::whereIn('status_id', [1, 2, 3])
->whereBetween('created_at', [$date_from, $date_to])
->get();
$active_records = $result->where('status_id', 1);
$pending_records = $result->where('status_id', 2);
$closed_records = $result->where('status_id', 3);
终端仅出现在源自raise
(声明)的规则中:
stmt
列表理解的第一部分是stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (... | flow_stmt | ...)
flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
raise_stmt: 'raise' [test ['from' test]]
(布尔值或表达式)或test
(star_expr
):
*expr
重点是无法从atom: ... | '[' [testlist_comp] ']' | ...
testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
(列表理解的左侧)派生一条语句。因此,您的表达在语法上是错误的。
正如@Neb在评论中指出的那样,试图返回一个(test|star_expr)
的列表理解没有意义。
您可能还记得raise
是Python 2中的一条语句,并成为Python 3中的一个函数。
Python 2:
print
Python 3:
>>> [print(1) for _ in range(1)]
File "<stdin>", line 1
[print(1) for _ in range(1)]
^
SyntaxError: invalid syntax
列表理解现在在语法上是正确的。同样,没有语法规则会阻止您编写此代码:
>>> [print(1) for _ in range(1)]
1
[None]
但是语义仍然不清楚:您要执行操作(即使用功能的副作用)还是要建立列表?请记住,列表理解是功能语言的借用,尤其是我认为是Haskell。因此,他们不在这里执行操作。
我对@ answer”问题的Is it Pythonic to use list comprehensions for just side effects?引用@Mark Ransom的评论:
我会更进一步地指出,列表理解内的副作用是不寻常的,意外的,因此是邪恶的,即使您在完成操作时使用结果列表也是如此。 –马克·勒索姆
我使用以下经验法则:即使您使用结果,也要避免列表理解中的任何副作用。