为什么在使用 >>= 运算符时出现语法错误?
Why am I getting a syntax error when using the >>= operator?
注意:我正在导入parsec library, which overloads the >>=
(i.e. - __irshift()__
) operator。
以下Python代码:
#! /usr/bin/env python
# irshift_debug.py
from parsec import *
def id(x):
"""Identity parser."""
return string("").result(x)
testp = digit() >>= id
print(testp.parse("5"))
产量:
$ ./irshift_debug.py
File "./irshift_debug.py", line 9
testp = digit() >>= id
^
SyntaxError: invalid syntax
但是,如果我将违规行更改为:
testp = digit().bind(id)
然后我得到:
$ ./irshift_debug.py
5
符合预期。
我认为 >>=
是 bind()
的中缀等价物;
这不正确吗?
因为>>=
是语句,不是表达式。它不会计算出可以分配给 testp
.
的结果
也许您正在寻找这个?
testp = digit >> id
我既没有使用过 Parsec 也没有使用过 Haskell,所以我无法说明在这个库的上下文中的预期用途。但是,我相信您在这里感到困惑的主要原因是 Python 中的 augmented assignment statements work differently than operators, and therefore reimplementing them works slightly differently as well. (Unlike in C and many other languages, 。)
所以你已经看到了这段代码:
def __irshift__(self, other):
'''Implements the `(>>=)` operator, means `bind`.'''
return self.bind(other)
不是很明显的是,因为这是覆盖扩充赋值,而不是运算符,returned 值用于重新分配左侧的原始项目。也就是说,这段代码:
a >>= b
是不是与简单的相同:
a.bind(b)
相反,它(基本上)等同于:
a = a.bind(b)
如 中所述,生成的赋值是一个语句,而不是一个表达式,最终 return 根本不是一个值(甚至 None
也不是)。赋值语句的右半部分必须是一个表达式;它不能是另一个赋值语句1。就像在 Python 中一样,你不能做 2:
这样的事情
a = b += c
所以你也做不到:
a = b >>= c
...即使您重新实现了 >>=
.
1 唯一的部分例外是最近添加的 assignment expression,但它(有意)在使用上受到限制,在这里不会帮助你。
2 另一方面,“chained assignment”,例如a = b = c
、 有效。这是一种特殊情况,因为它不仅仅是 return 它们的值的一系列运算符; a = (b = c)
仍然是语法错误。相反,它都被解析为一个赋值语句。
这是一个设计错误。
我转而使用 >=
作为 bind()
的运算符并弃用了 >>=
。 parsec.py 的新版本已上传到 pypi。
注意:我正在导入parsec library, which overloads the >>=
(i.e. - __irshift()__
) operator。
以下Python代码:
#! /usr/bin/env python
# irshift_debug.py
from parsec import *
def id(x):
"""Identity parser."""
return string("").result(x)
testp = digit() >>= id
print(testp.parse("5"))
产量:
$ ./irshift_debug.py
File "./irshift_debug.py", line 9
testp = digit() >>= id
^
SyntaxError: invalid syntax
但是,如果我将违规行更改为:
testp = digit().bind(id)
然后我得到:
$ ./irshift_debug.py
5
符合预期。
我认为 >>=
是 bind()
的中缀等价物;
这不正确吗?
因为>>=
是语句,不是表达式。它不会计算出可以分配给 testp
.
也许您正在寻找这个?
testp = digit >> id
我既没有使用过 Parsec 也没有使用过 Haskell,所以我无法说明在这个库的上下文中的预期用途。但是,我相信您在这里感到困惑的主要原因是 Python 中的 augmented assignment statements work differently than operators, and therefore reimplementing them works slightly differently as well. (Unlike in C and many other languages,
所以你已经看到了这段代码:
def __irshift__(self, other):
'''Implements the `(>>=)` operator, means `bind`.'''
return self.bind(other)
不是很明显的是,因为这是覆盖扩充赋值,而不是运算符,returned 值用于重新分配左侧的原始项目。也就是说,这段代码:
a >>= b
是不是与简单的相同:
a.bind(b)
相反,它(基本上)等同于:
a = a.bind(b)
如 None
也不是)。赋值语句的右半部分必须是一个表达式;它不能是另一个赋值语句1。就像在 Python 中一样,你不能做 2:
a = b += c
所以你也做不到:
a = b >>= c
...即使您重新实现了 >>=
.
1 唯一的部分例外是最近添加的 assignment expression,但它(有意)在使用上受到限制,在这里不会帮助你。
2 另一方面,“chained assignment”,例如a = b = c
、 有效。这是一种特殊情况,因为它不仅仅是 return 它们的值的一系列运算符; a = (b = c)
仍然是语法错误。相反,它都被解析为一个赋值语句。
这是一个设计错误。
我转而使用 >=
作为 bind()
的运算符并弃用了 >>=
。 parsec.py 的新版本已上传到 pypi。