2017-07-07 31 views
24

我有一个叫Time的类,我需要实现一个Frequency类。我如何实现将int s或float s分配给Time的实例以获得Frequency的实例?用Python中我的类的实例划分数字

我已经知道__div____truediv____floordiv__和其他Python特殊方法,我已经使用他们在我的代码用数字或其他类的实例来划分的类的实例,但我不能找到一种方法来划分数由我的班级的一个实例。

是否有可能实现用Python中的类的实例分隔数字?

+2

具有不同类每一种类型的数量听起来像一个道路疯狂...你是如何单元之间的不匹配处理? – jpmc26

+0

我使用'isinstance',我只需要实现时间和频率。 – Lucidiot

回答

27

__rtruediv__方法就是你要找的。 当执行x/y时,如果type(x)未实现__div__(self, other)方法,其中other可以是type(y)类,则执行type(y).__rtruediv__(y, x),然后返回其结果。

用法:

class Foo: 
    def __init__(self, x): 
     self.x = x 

    def __truediv__(self, other): 
     return self.x/other 

    def __rtruediv__(self, other): 
     return other/self.x 
>>> f = Foo(10)  
>>> f/10 
1.0 
>>> 10/f 
1.0
3

您需要执行__rtruediv____rfloordiv__

the documentation

object.__radd__(self, other) 
object.__rsub__(self, other) 
object.__rmul__(self, other) 
object.__rmatmul__(self, other) 
object.__rtruediv__(self, other) 
object.__rfloordiv__(self, other) 
object.__rmod__(self, other) 
object.__rdivmod__(self, other) 
object.__rpow__(self, other) 
object.__rlshift__(self, other) 
object.__rrshift__(self, other) 
object.__rand__(self, other) 
object.__rxor__(self, other) 
object.__ror__(self, other) 

这些方法

被称为执行二进制算术运算 (+, - ,*,@,/,//%,divmod(),POW() **,< <,>>,&,^,|)与 反映(交换)的操作数。这些函数仅在左操作数不支持相应操作[3]和 操作数具有不同类型时才会调用。 [4]例如,要评估 表达式x-y,其中y是具有方法012xx__rsub__()方法的类的实例,如果x.__sub__(y)返回NotImplemented,则调用y.__rsub__(x)

9

是。您只需确保Time.__rtruediv__()在接收到浮点数或整数时返回Frequency实例。

用法:

>>> 100/Time(2) 
Frequency(50.0) 
>>> 2.5/Time(5) 
Frequency(0.5) 

实现:

class Time: 
    def __init__(self, value): 
    self.value = value 

    def __rtruediv__(self, other): 
    if not isinstance(other, (int, float)): 
     return NotImplemented 
    return Frequency(other/self.value) 

class Frequency: 
    def __init__(self, value): 
    self.value = value 

    def __repr__(self): 
    return '{}({})'.format(self.__class__.__name__, self.value) 

Python文档包含implementing the arithmetic operations您的自定义类的完整示例。

处理不兼容类型的正确方法是返回特殊值NotImplemented

NotImplemented

应该由二进制 特殊的方法被返回(例如__eq__()__lt__()__add__()__rsub__()等) 以指示该操作不相对于实现为将 特别值其他类型

假设您尝试使用不受支持的复数,则返回NotImplemented将甚至会导致带有正确错误消息的TypeError。 (至少在Python 3)

>>> 100j/Time(2) 

Traceback (most recent call last): 
    File "python", line 1, in <module> 
TypeError: unsupported operand type(s) for /: 'complex' and 'Time'