是否可以使用__rmod__覆盖str的%行为? [英] Is it possible to overwrite str's % behaviour using __rmod__?

查看:81
本文介绍了是否可以使用__rmod__覆盖str的%行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做:

x %doSomething% y

对于x和y来说,这很容易做到(请参见下面的代码),除非x是str.

which is easy enough to do (see code below) for any x and any y except in the case that x is a str.

是否有任何方法(例如添加特殊方法或引发特定错误)导致旧样式字符串格式化失败(类似于1%doSomthing因TypeError失败而失败)并还原为doSomething对象中定义的__rmod__方法?

Is there any way (e.g. adding a special method or raising a specific error) to cause old style string formatting to fail (similarly to how 1 %doSomthing fails with a TypeError) and revert to the __rmod__ method defined in the doSomething object?

class BinaryMessage(object):
  def __init__(self, fn):
    self._fn = fn
  def __rmod__(self, LHS):
    return BinaryMessagePartial(self._fn, LHS)

class BinaryMessagePartial(object):
  def __init__(self, fn, LHS):
    self._fn = fn
    self._LHS = LHS
  def __mod__(self, RHS):
    return self._fn(self._LHS, RHS)

def _doSomething(a , b):
  return a + b

doSomething = BinaryMessage(_doSomething)

result = 5 %doSomething% 6
assert result == 11

推荐答案

注意:我提交了适用于Python 2.7和3.5及更高版本的补丁.这些已经着陆,并且是2.7.14、3.5.4、3.6.1和3.7的一部分,而OP示例现在可以按预期运行.有关旧版本,请参见下文.

Note: I submitted patches for Python 2.7, and 3.5 and up. These have landed and are part of 2.7.14, 3.5.4, 3.6.1 and 3.7, where the OP example now works as expected. For older versions, see below.

不幸的是,这在Python中目前是不可能的.该行为在评估循环中进行了硬编码:

Unfortunately, this is not currently possible in Python. The behaviour is hardcoded in the evaluation loop:

TARGET(BINARY_MODULO) {
    PyObject *divisor = POP();
    PyObject *dividend = TOP();
    PyObject *res = PyUnicode_CheckExact(dividend) ?
        PyUnicode_Format(dividend, divisor) :
        PyNumber_Remainder(dividend, divisor);

(来自 Python 3.5源代码,其中PyUnicode是Python str类型).

(From the Python 3.5 source code, where PyUnicode is the Python str type).

这很不幸,因为对于其他所有类型,您都可以通过使用右侧操作数的子类来阻止LHS.__mod__方法被调用;来自文档:

This is unfortunate, because for every other type you can prevent the LHS.__mod__ method to be invoked by using a subclass for the right-hand operand; from the documentation:

注意:如果右侧操作数的类型是左侧操作数类型的子类,并且该子类为操作提供了反射方法,则该方法将在左侧操作数的非反射方法之前调用.这种行为允许子类覆盖其祖先的操作.

Note: If the right operand’s type is a subclass of the left operand’s type and that subclass provides the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.

这将是这里唯一的选择,str % other从不返回NotImplemented所有 RHS类型被接受(实际的

This would have been the only option here, str % other never returns NotImplemented, all RHS types are accepted (the actual str.__mod__ method only accepts str objects for the RHS, but is not called in this case).

我认为这是Python中的错误,存档为 issue#28598 .

I consider this a bug in Python, filed as issue #28598.

这篇关于是否可以使用__rmod__覆盖str的%行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆