Class 方法调用两次
Class method calling twice
我有以下代码。
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" 两次?
-----编辑-----
另一个解决方案是使用 属性 和 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)
你调用它两次。一次在 print()
最后,一次在 m_est_maj
的调用中。
6 数学运算是相当便宜的运算。您可能不会通过缓存结果获得有意义的性能提升。但如果你愿意,你可以这样做。您可以从 __init__
调用 m_in_maj
并将结果保存到实例属性,然后引用它而不是函数调用。
或者您可以让函数检查实例属性是否已定义,在第一次调用时计算,并在后续调用时 return。
这是我看到的一种非常常见的通用方法:
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
你的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))
我有以下代码。
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" 两次?
-----编辑-----
另一个解决方案是使用 属性 和 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)
你调用它两次。一次在 print()
最后,一次在 m_est_maj
的调用中。
6 数学运算是相当便宜的运算。您可能不会通过缓存结果获得有意义的性能提升。但如果你愿意,你可以这样做。您可以从 __init__
调用 m_in_maj
并将结果保存到实例属性,然后引用它而不是函数调用。
或者您可以让函数检查实例属性是否已定义,在第一次调用时计算,并在后续调用时 return。
这是我看到的一种非常常见的通用方法:
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
你的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))