2017-01-08 3 views
-1

У меня есть следующий код.Метод вызова класса дважды

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

'm_in_maj()' вызывается в 'm_est_maj () 'function – Kidus

+0

Не называть его в' m_est_maj' –

+0

Да, но мне нужно это значение, чтобы использовать его на m_est_maj. – Eduardo

ответ

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, это могло бы быть более вещий, чтобы сделать что-то вроде этого:

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 
+0

Спасибо Dan. Может быть, я могу использовать переменную для хранения результата? или просто вызвать метод для получения возвращаемого значения? – Eduardo

+0

см. Пример кода я добавил. –

+0

Большое спасибо Dan. Извините, мое невежество, но что делает «hasattr»? Убедитесь, что атрибут уже установлен? – Eduardo

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)) 
+0

Спасибо, я попробую этот метод. – Eduardo

+0

Я бы сказал, что такая логика принадлежит внутри класса. Вы взяли логику _out_ класса и делегировали ее в _caller_, что нарушает инкапсуляцию, которую вы получаете в классе. –

+0

@DanFarrell Я бы согласился в другой ситуации, но в Python нет инкапсуляции. Ваше решение создает инкапсуляцию, которая может быть хорошей, хотя в целом она не нужна. Мое решение позволяет контролировать получателя. Это два разных подхода, но я не думаю, что один лучше, чем другой, это просто зависит от ситуации. –

Смежные вопросы