Пишу код для расчетов, начал тестирование и столкнулся с проблемой, при попытке получить ответ выскакивает ошибка:
Traceback (most recent call last):
File "G:\LARIS\tests\test_centrifugal_injector.py", line 51, in <module>
test()
File "G:\LARIS\tests\test_centrifugal_injector.py", line 34, in test
print(injector.equivalent_geometric_characteristic_injector)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\iru\AppData\Local\Programs\Python\Python312\Lib\functools.py", line 995, in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "G:\LARIS\src\centrifugal_injector_calc.py", line 89, in equivalent_geometric_characteristic_injector
return self.geometric_characteristics_injector() / (1 + self.coefficient_friction /
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'float' object is not callable
Как я могу это исправить?
Основной файл:
from dataclasses import dataclass
from functools import cached_property
from abc import ABC, abstractmethod
@dataclass(frozen=True)
class Injector(ABC):
@abstractmethod
def geometric_characteristics_injector(self) -> float:
""""""
raise NotImplementedError
@cached_property
def equivalent_geometric_characteristic_injector(self) -> float:
"""Возвращает эквивалентную геометрическую характеристику"""
return self.geometric_characteristics_injector() / 2.0
@dataclass(frozen=True)
class CentrifugalInjector(Injector):
@cached_property
def geometric_characteristics_injector(self) -> float:
"""Возвращает геометрическую характеристику центробежной форсунки"""
return 2.0
@dataclass(frozen=True)
class ScrewInjector(Injector):
@cached_property
def geometric_characteristics_injector(self) -> float:
"""Возвращает геометрическую характеристику шнековой форсунки"""
return 1.0
from src.centrifugal_injector_calc import CentrifugalInjector, ScrewInjector
def test() -> None:
common = {
"outer_diameter_injector": 5,
"side_wall_thickness_injector": 0.1,
"number_input_tangential_holes": 2,
"diameter_input_tangential_holes": 0.1,
"length_input_tangential_holes": 0.1,
"relative_length_twisting_chamber": 0.1,
"diameter_injector_nozzle": 0.1,
"relative_length_injector_nozzle": 0.1,
"angle_nozzle_axis": 0.1,
"mass_flow_rate": 0.1,
"viscosity": 0.1,
"cross_sectional_area_one_passage_channel": 0.1,
"density_fuel_component_front_injector": 0.1,
"density_combustion_products": 0.1,
"surface_tension_coefficient": 0.1,
}
injector = CentrifugalInjector(**common)
if __name__ == "__main__":
test()
Все базовые вычисления выполняются в основном Injector
классе, а два оставшихся отвечают за выбор конфигурации этого расчета, чтобы не было ошибки из-за прямого вызова основного класса, он абстрактен, как и функция, получающая конфигурацию. данные
Кроме того, ваша обратная трассировка ошибок ссылается на два разных файла, а вы предоставили только часть одного (какого?)
@ThierryLathuille Да, я ошибся, добавил второй файл при запуске первого
В ваших файлах слишком много кода, оставьте только минимум, чтобы воспроизвести проблему.
@ThierryLathuille ОК, вот сокращенный пример кода
Если self.geometric_characteristics_injector
является свойством, то вам следует использовать его с self.geometric_characteristics_injector
(который является числом с плавающей запятой), а не self.geometric_characteristics_injector()
, которое пытается вызвать это число с плавающей запятой.
@ThierryLathuille Ладно, допустим, это не будет свойство, но тогда будет еще одна ошибка в работе, но как заставить код работать в этом случае?
Я не понимаю ваш последний вопрос. Если это не свойство, а обычный метод, просто вызовите его, как вы это сделали. Если это свойство, просто используйте его, как если бы это был обычный атрибут.
Расширяя ответ @Thierry Lathuille в их комментарии:
@dataclass(frozen=True)
class ScrewInjector(Injector):
@cached_property
def geometric_characteristics_injector(self) -> float:
"""Возвращает геометрическую характеристику шнековой форсунки"""
return 1.0
Вы объявляете метод geometric_characteristics_injector
, который сам по себе должен вызываться с помощью self.geometric_characteristics_injector()
.
Но декоратор @cached_property перезаписывает этот метод специальным аксессором, который ведет себя как свойство. Итак, после оформления правильно использовать self.geometric_characteristics_injector
без скобок.
Поэтому уберите скобки в
@cached_property
def equivalent_geometric_characteristic_injector(self) -> float:
"""Возвращает эквивалентную геометрическую характеристику"""
return self.geometric_characteristics_injector / 2.0
# ^^ no parenthesis
Если используемый вами API требует, чтобы этот метод вел себя как метод, вам следует использовать декоратор @cached вместо @cached_property
. Тогда вы можете оставить скобки.
Это не совсем то, что нужно. Посмотрите, код построен таким образом, что Geometric_characteristics_injector — это абстрактный метод, принимающий значение одного из двух оставшихся классов, в зависимости от того, какой из них мы используем. Вы не можете просто оставить значение в этой функции
Похоже, есть две проблемы.
Метод Geometric_characteristics_injector определен как свойство, но метод *equiqual_geometric_characteristic_injector* обрабатывает его как метод:
@cached_property
def equivalent_geometric_characteristic_injector(self) -> float:
"""Возвращает эквивалентную геометрическую характеристику"""
return self.geometric_characteristics_injector() / (1 + self.coefficient_friction /
2 * self.radius_tangential_inlet *
(self.radius_tangential_inlet +
self.diameter_input_tangential_holes -
self.radius_injector_nozzle))
Чтобы это исправить, вам нужно удалить «()» в первой строке оператора return.
@cached_property
def equivalent_geometric_characteristic_injector(self) -> float:
"""Возвращает эквивалентную геометрическую характеристику"""
return self.geometric_characteristics_injector / (1 + self.coefficient_friction /
2 * self.radius_tangential_inlet *
(self.radius_tangential_inlet +
self.diameter_input_tangential_holes -
self.radius_injector_nozzle))
Вышеупомянутое решит конкретную ошибку, с которой вы столкнулись. Однако похоже, что в ваших конкретных тестах соотношение_live_section_injector_nozzle будет иметь отрицательное число внутри выражения квадратного корня.
Мне удалось решить эту проблему, используя комплексные числа:
from cmath import sqrt as csqrt
#other imports
#...
@cached_property
def ratio_live_section_injector_nozzle(self) -> float:
linear_fraction_geometric_characteristic = self.equivalent_geometric_characteristic_injector / (2 * sqrt(2))
quadratic_fraction_geometric_characteristic = csqrt(self.equivalent_geometric_characteristic_injector ** 2 / 8 - 1 / 27)
result = 1 / ((linear_fraction_geometric_characteristic + quadratic_fraction_geometric_characteristic) ** (1 / 3)
+ (linear_fraction_geometric_characteristic - quadratic_fraction_geometric_characteristic) **
(1 / 3)) ** 2
return result.real # Return only the real part
Приведите, пожалуйста, минимальный воспроизводимый пример - акцент на минимальном.