用于路径传播的链式运算符重载

时间:2018-03-15 09:52:55

标签: python operator-overloading

我想在python中实现一个简单的光传播模型。规则是,如果我链接三个元素 m0 - > M1-> m2 我将得到的系统是:

  • tau = tau0 * tau1 * tau2
  • B = B2 + B1 * tau2 + B0 * tau2 * tau1

(tau是传输,B是背景)。

我想实现重载__gt__运算符,以便我可以声明:

m0 = Mirror(0.9, 10)
m1 = Mirror(0.8, 11)
m2 = Mirror(0.7, 12)
x = m0 > m1 > m2

到目前为止,我写了这个:

class OpticalElement:
    def __init__(self, trans, background):
        self.trans = trans
        self.background = background

class Mirror(OpticalElement):       
    def __gt__(self, other):
        if isinstance(other, Mirror):
            tau = self.trans * other.trans
            bkg = other.background + other.trans * self.background
            return Mirror(tau, bkg)
        else:
            return NotImplemented

然而,这段代码似乎只能获得最右边元素的传输和背景:

x = m0 > m1 > m2
x.trans

返回0.56,而我期待0.504。 背景表现相同,我得到19.7而不是25.3(第一个元素被忽略)。

你们对使用运算符重载如何实现多个链式元素有什么想法吗?(将括号工作,但我希望有更清晰的代码)。

谢谢!

安德鲁

2 个答案:

答案 0 :(得分:2)

m0 > m1 > m2相当于(m0 > m1) and (m1 > m2)

由于m0 > m1将被视为Trueand将测试m1 > m2并返回其值,即您获得的0.56。

您可以使用乘法运算符,它将按预期工作:

class OpticalElement:
    def __init__(self, trans, background):
        self.trans = trans
        self.background = background

class Mirror(OpticalElement):       
    def __mul__(self, other):
        if isinstance(other, Mirror):
            tau = self.trans * other.trans
            bkg = other.background + other.trans * self.background
            return Mirror(tau, bkg)
        else:
            return NotImplemented

m0 = Mirror(0.9, 10)
m1 = Mirror(0.8, 11)
m2 = Mirror(0.7, 12)
x = m0 *m1 * m2
print(x.trans)
#0.504

答案 1 :(得分:1)

链式比较的工作方式是m0 > m1 > m2评估为(m0 > m1) and (m1 > m2),结果为m1 > m2x and y如果y则返回x是真实的。 所以这就是为什么你的代码似乎只能得到最合适的比较。

相反,你可以这样做 x = (m0 > m1) > m2。 它以给定的顺序评估两个>运算符。 这导致

x = (m0 > m1) > m2
print(x.trans) # 0.504