__rrshift__可以接受多个参数吗?

时间:2019-08-26 08:47:37

标签: python-3.x

我正在尝试在一个类上重载__rrshift__方法。基本实现如下:

class A:
    def __rrshift__(self, arg0):
        print(f'called A.__rrshift__ with arg0={arg0}')

a = A()
42 >> a

在这里我得到了预期的结果:

called A.__rrshift__ with arg0=42

但是,如果我使用多个参数调用此方法,则仅使用最后一个参数:

'hello', 'world' >> a

哪个返回:

called A.__rrshift__ with arg0=world

如果我尝试向__rrshift__方法添加参数,则行为不会按我预期的那样修改:

class B:
    def __rrshift__(self, arg0, arg1=None):
        print(f'called B.__rrshift__ with arg0={arg0}, arg1={arg1}')

b = B()
42 >> b
'hello', 'world' >> b

# called B.__rrshift__ with arg0=42, arg1=None
# called B.__rrshift__ with arg0=world, arg1=None

__rrshift__方法是否可以考虑多个参数?

2 个答案:

答案 0 :(得分:1)

我不确定您要做什么,但是如果您只需要提供一些args(最终是kwargs),这可能会向您展示如何实现:

class A:
    def __rrshift__(self, *args):
        if len(args) > 1:
            print(f'called A.__rrshift__ with arg={", ".join(args)}')
        else:
            print(f'called A.__rrshift__ with arg={args[0]}')

a = A()
a.__rrshift__('hello', 'world')
a.__rrshift__(42)

#called A.__rrshift__ with arg=hello, world
#called A.__rrshift__ with arg=42

答案 1 :(得分:1)

恐怕不可能。

__rrshift__,例如__add____sub__等。是二元运算符。它们正好接受两个参数:selfwhatever_other_argument

当然,您可以通过显式调用这些方法来欺骗系统,然后它们将能够接受所需的任意多个参数,但是如果您使用>>,{{1} },+等语言,那么该语言的语法将强制他们完全接受两个参数。

您可能可以通过使用-模块修改Python语法的技巧来修改它,但这不再是Python。

根据the grammar,这是Python解析器如何查看ast的地方:

a, b >> c

产生[sic]元组的语法中的结果似乎如下:

>>> ast.dump(ast.parse('a, b >> c'))
# I prettified this myself. The actual output of `dump` is horrendous looking.
Module(
 body=[
  Expr(
   # Build a tuple...
   value=Tuple(elts=[
    Name(id='a', ctx=Load()), # ...containing `a`...
    # ...and the result of a BINARY OPERATOR (RShift)...
    BinOp(
     left=Name(id='b', ctx=Load()), # ...which is applied to `b`...
     op=RShift(),
     right=Name(id='c', ctx=Load()) # ...and `c`
    )
    ],
    ctx=Load()
   )
  )
  ]
 )

如您所见,然后继续解析testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] 生产,然后将其解压缩到test生产,然后到达以下生产:

expr

因此,shift_expr: arith_expr (('<<'|'>>') arith_expr)* 中的第一个test解析为testlist_star_expr,第二个解析为atom: NAME。后来,最终构造了元组。

相关问题