Python:对于超类中定义的运算符,我可以有一个子类返回其自身类型的实例吗?

克林特·吉文斯

在Python(2.7)中,我想创建一个有理数类,以模仿Fraction类的行为(在模块分数中),但重写__repr__方法以匹配__str__的结果。最初的想法只是出于我自己的想法,只是为了让IDLE输出看起来更友好。但是现在,我对了解潜在的继承/类型问题(我认为可能是普遍感兴趣的)更感兴趣,而不是针对此特定用例找到解决方法,这是很简单的。

问题是,我也想继承所有数值运算符的功能(方法__add __,__ sub__等),但是结果是我的子类的实例,而不是Fraction的实例。那就是我想要的,但是发生了:

class Q(Fraction):
    def __repr__(self):
        return str(self)

>>> Q(1,2)
1/2
>>> Q(1,2) + Q(1,3)
Fraction(5, 6)

发生这种情况是因为Fraction中定义的运算符返回Fraction实例。当然,我可以单独覆盖所有这些魔术方法,调用父类进行数学运算然后强制转换为我的类型,但是我觉得应该有一种方法可以通用地处理这种重复情况(即,无需编写“ def” 20次)。

我还考虑过使用__getattribute__来拦截方法调用,但这似乎很不雅致,极其脆弱,并且可以保证在甚至比此复杂得多的情况下失败。(我知道__getattr__是首选,但似乎不会捕获我感兴趣的方法调用,因为它们是在基类中定义的!)

鉴于我不是基类的作者,是否有比单独覆盖每个方法更好的方法?

科利·布里格曼

这有点工作,但是您可以包装它并创建一个委托人。实际上,我做了与您所做的类似的事情,以创建一个默认情况下以十六进制打印的int。我自己的一个子类中的一个更好的例子,该子类将int子类化,以允许按位读取(写操作显然是行不通的,因为int是不可变的,因此此特定代码并没有走得太远……)。也许有很多示例代码,但是显示了如何使用它:

# I stole this decorator from another stackoverflow recipe :) 
def returnthisclassfrom(specials):
  specialnames = ['__%s__' % s for s in specials.split()]
  def wrapit(cls, method):
    return lambda *a: cls(method(*a))
  def dowrap(cls):
    for n in specialnames:
      method = getattr(cls, n)
      setattr(cls, n, wrapit(cls, method))
    return cls
  return dowrap

def int_getslice(self, i, j):
    # NON-pythonic, will return everything inclusive i.e. x[5:3] returns 3 bits, not 2.
    # Because that's what users normally expect.
    # If you're a purist, modify below.
    if i > 1000000 or j > 1000000:
        raise ValueError, 'BitSize limited to 1 million bits'
    lo = min(i,j)
    hi = max(i,j)
    mask = (1<<((hi-lo)+1))-1

    return (self>>lo) & mask

def int_getitem(self, i):
    # Safety limit
    if i > 1000000:
        raise ValueError, 'BitSize limited to 1 million bits'
    return (self>>i)&1

def int_iter(self):
    # since getitem makes it iterable, override
    raise AttributeError, 'int object is not iterable'

@returnthisclassfrom('abs add and div floordiv lshift mod mul neg or pow radd rand rdiv rdivmod rfloordiv rlshift rmod rmul ror rpow rrshift rshift rsub rxor rtruediv sub truediv xor trunc')
class BitSliceInt(long):
  __getslice__ = int_getslice
  __getitem__ = int_getitem
  __iter__ = int_iter

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我可以在Python中定义一个“非”运算符吗?

来自分类Dev

在PHPStorm中,当我有一个超类方法返回每个子类的不同类型时,如何使类型提示起作用

来自分类Dev

创建一个子类的多个实例,只有一个超类的实例

来自分类Dev

从超类实例化一个子类

来自分类Dev

我可以在父类中声明一个占位符变量,在子类中以不同类型声明它吗?

来自分类Dev

快速从其基类返回一个子类

来自分类Dev

子类使用自身内的另一个子类扩展相同的超类

来自分类Dev

我可以在另一个子类中引用一个子类吗?

来自分类Dev

为什么一个类的实例可以访问其自身类型的另一个实例的私有字段?

来自分类Dev

有没有一种合适的方法来实现一个子类,该子类具有与Python中其超类不同的方法签名?

来自分类Dev

我可以从子类以外的其他类中调用抽象基类的公共赋值运算符吗?

来自分类Dev

我如何使用|| 运算符,以便销毁2个实例中的任何一个?

来自分类Dev

在Python中实例化时选择一个子类

来自分类Dev

我可以只使用一个结果的三元运算符吗?

来自分类Dev

我可以将运算符添加到现有的类中吗?

来自分类Dev

我可以在Python中为内置类重载运算符吗?

来自分类Dev

在C ++中,是否有可能在超类中有一个方法,当每个子类调用该方法时,该方法会向该子类返回一个shared_ptr?

来自分类Dev

为什么用户定义的模板化转换运算符可以确定其返回类型?

来自分类Dev

我可以在子类中重新定义超类的属性吗?(也许是 c# 的新修饰符?)

来自分类Dev

我可以在python中执行两个以上对象的运算符重载吗?

来自分类Dev

我可以对2个外观相似的类使用类型强制转换运算符吗?

来自分类Dev

我可以在 python 3 中为描述符定义一个 add 方法吗?

来自分类Dev

在一个子类中实例化一个类并在另一个子类中访问它的实例

来自分类Dev

是否可以创建一个类,其每个实例将具有不同的类型?

来自分类Dev

我可以指定一个类实例可以转换为某种类型吗?

来自分类Dev

是否有一个像“扫描”一样工作的运算符,但让我返回IObservable <TResult>而不是IObservable <TSource>吗?

来自分类Dev

是否有一个像“扫描”一样工作的运算符,但让我返回IObservable <TResult>而不是IObservable <TSource>吗?

来自分类Dev

在超类和方法调用中声明一个子类

来自分类Dev

多个子类继承其父类的一个实例

Related 相关文章

  1. 1

    我可以在Python中定义一个“非”运算符吗?

  2. 2

    在PHPStorm中,当我有一个超类方法返回每个子类的不同类型时,如何使类型提示起作用

  3. 3

    创建一个子类的多个实例,只有一个超类的实例

  4. 4

    从超类实例化一个子类

  5. 5

    我可以在父类中声明一个占位符变量,在子类中以不同类型声明它吗?

  6. 6

    快速从其基类返回一个子类

  7. 7

    子类使用自身内的另一个子类扩展相同的超类

  8. 8

    我可以在另一个子类中引用一个子类吗?

  9. 9

    为什么一个类的实例可以访问其自身类型的另一个实例的私有字段?

  10. 10

    有没有一种合适的方法来实现一个子类,该子类具有与Python中其超类不同的方法签名?

  11. 11

    我可以从子类以外的其他类中调用抽象基类的公共赋值运算符吗?

  12. 12

    我如何使用|| 运算符,以便销毁2个实例中的任何一个?

  13. 13

    在Python中实例化时选择一个子类

  14. 14

    我可以只使用一个结果的三元运算符吗?

  15. 15

    我可以将运算符添加到现有的类中吗?

  16. 16

    我可以在Python中为内置类重载运算符吗?

  17. 17

    在C ++中,是否有可能在超类中有一个方法,当每个子类调用该方法时,该方法会向该子类返回一个shared_ptr?

  18. 18

    为什么用户定义的模板化转换运算符可以确定其返回类型?

  19. 19

    我可以在子类中重新定义超类的属性吗?(也许是 c# 的新修饰符?)

  20. 20

    我可以在python中执行两个以上对象的运算符重载吗?

  21. 21

    我可以对2个外观相似的类使用类型强制转换运算符吗?

  22. 22

    我可以在 python 3 中为描述符定义一个 add 方法吗?

  23. 23

    在一个子类中实例化一个类并在另一个子类中访问它的实例

  24. 24

    是否可以创建一个类,其每个实例将具有不同的类型?

  25. 25

    我可以指定一个类实例可以转换为某种类型吗?

  26. 26

    是否有一个像“扫描”一样工作的运算符,但让我返回IObservable <TResult>而不是IObservable <TSource>吗?

  27. 27

    是否有一个像“扫描”一样工作的运算符,但让我返回IObservable <TResult>而不是IObservable <TSource>吗?

  28. 28

    在超类和方法调用中声明一个子类

  29. 29

    多个子类继承其父类的一个实例

热门标签

归档