调用两次的类方法

时间:2017-01-08 17:24:21

标签: python methods call

我有以下代码。

class DobleTSim():
    def __init__(self, bf, hw, tf, tw):
        self.bf = bf
        self.hw = hw  
        self.tf = tf
        self.tw = tw

    def m_in_maj(self):
        print('foo')
        return 2 * (self.bf * self.tf * (self.tf / 2 + self.hw / 2))


    def m_est_maj(self):
        return self.m_in_maj() / ((self.hw + 2 * self.tf) / 2)

A = DobleTSim(200, 500, 12, 12)

print(A.m_in_maj(), A.m_est_maj())

当我执行代码时,输​​出为:

foo
foo
1228800.0 4690.076335877862

如何避免执行方法" m_in_maj"两次?

----- ----- EDIT

另一种解决方案可以是使用属性 lru_cache 装饰器。使用它时有缺点吗?。

import functools

class DobleTSim():
    def __init__(self, bf, hw, tf, tw):
        self.bf = bf
        self.hw = hw  
        self.tf = tf
        self.tw = tw

    @property
    @functools.lru_cache()
    def m_in_maj(self):
        print('foo')
        self.a = 2 * (self.bf * self.tf * (self.tf / 2 + self.hw / 2))
        return self.a

    def m_est_maj(self):
        return self.m_in_maj / ((self.hw + 2 * self.tf) / 2)

2 个答案:

答案 0 :(得分:3)

调用它两次。进入print()后,一旦进入m_est_maj

6次数学运算是一项相当便宜的操作。通过缓存结果,您可能无法获得有意义的性能提升。但如果你愿意,你可以这样做。您可以从m_in_maj调用__init__并将结果保存到实例属性,并参考该函数而不是函数调用。

或者您可以检查函数是否已定义实例属性,在第一次调用时计算,以及在后续调用时返回。

这是我看到的非常常见的一般方法:

class DobleTSim():
    def __init__(self, bf, hw, tf, tw):
        self.bf = bf
        self.hw = hw
        self.tf = tf
        self.tw = tw

    def m_in_maj(self):
        if not hasattr( self, '_m_in_maj_result'):
            print('foo')
            self._m_in_maj_result =  \
                2 * (self.bf * self.tf * (self.tf / 2 + self.hw / 2))
        return self._m_in_maj_result


    def m_est_maj(self):
        return self.m_in_maj() / ((self.hw + 2 * self.tf) / 2)

A = DobleTSim(200, 500, 12, 12)

print(A.m_in_maj(), A.m_est_maj())

基于How to know if an object has an attribute in Python,做这样的事情可能更具pythonic:

def m_in_maj(self):
    try:
        return self._m_in_maj_result
    except AttributeError:
        print('foo')
        self._m_in_maj_result =  \
            2 * (self.bf * self.tf * (self.tf / 2 + self.hw / 2))
        return self._m_in_maj_result

答案 1 :(得分:0)

您的m_in_maj方法在m_est_maj方法中调用:

def m_est_maj(self):
    return self.m_in_maj() / ((self.hw + 2 * self.tf) / 2)

相反,给它一个可选参数,并且仅在未传递此参数时调用m_in_maj

def m_est_maj(self, x=None):
    if x is None:
        x = self.m_in_maj()
    return x / ((self.hw + 2 * self.tf) / 2)

然后,在致电m_est_maj时:

x = A.m_in_maj()
print(x, A.m_est_maj(x))