Performance von `property`-Dekorator
Verfasst: Freitag 24. Mai 2024, 18:36
Hallo,
ich habe noch eine weitere Frage, die mir gerade in den Kopf kam.
Ich mag den `property`-Dekorator ziemlich, bin mir aber nicht sicher ob das immer so sinnvoll ist.
Sagen wir ich habe eine Beispiel-Klasse `Gas`. Das Gas kann ein Gemisch aus unterschiedlichen Gasen sein. Für Berechnungen brauche ich beispielsweise die Dichte des Gasgemisches. Also hat die Funktion, die mir die Dichte berechnet ein `@property` bekommen. Die Klasse, mal auf die eine Eigenschaft herunter gebrochen sieht so aus:
Sagen wir ich will jetzt 100 Maschinen berechnen, die alle dieses Gaseigenschaft zur Berechnung benötigen, vielleicht wird die Eigenschaft pro Berechnung 5 mal benötigt. Das würde bedeuten, dass die Dichte 500 mal neu berechnet wird und jedes mal das selbe Ergebnis kommt. Das ist ja schon recht unnötig. Mal allgemein betrachtet und unabhängig davon wie aufwändig die Berechnung ist.
Alternativ könnte ich so etwas machen:
Und müsste halt einmal die `calculate_density` Funktion aufrufen. Dabei gefällt mir nicht das meine `__init__` eine Reihe von `None`-Werten zu Beginn hat.
Gibt es hier eine Alternative? Gibt es eine Fausformel, wann man `property` verwendet und wann nicht mehr und wie geht man vor, wenn man es nicht mehr verwendet?
Vielen Dank und Grüße
Dennis
ich habe noch eine weitere Frage, die mir gerade in den Kopf kam.
Ich mag den `property`-Dekorator ziemlich, bin mir aber nicht sicher ob das immer so sinnvoll ist.
Sagen wir ich habe eine Beispiel-Klasse `Gas`. Das Gas kann ein Gemisch aus unterschiedlichen Gasen sein. Für Berechnungen brauche ich beispielsweise die Dichte des Gasgemisches. Also hat die Funktion, die mir die Dichte berechnet ein `@property` bekommen. Die Klasse, mal auf die eine Eigenschaft herunter gebrochen sieht so aus:
Code: Alles auswählen
from CoolProp.CoolProp import PropsSI
class Gas:
def __init__(
self,
components,
name_to_property,
):
self.components = components
self.name_to_property = name_to_property
if sum(self.components.values()) != 100:
raise ValueError(
f"Components must be 100%, now -> {list(components.values())}"
)
@classmethod
def from_components(
cls,
components,
temperature,
pressure,
):
try:
gas = cls(
components,
{
component_name: {
property_name: (
PropsSI(
property_code,
"T",
temperature,
"P",
pressure * 1e5,
component_name,
)
if property_name != "normdichte"
else PropsSI("D", "T", 273, "P", 1e5, component_name)
)
for property_name, property_code in [
("normdichte", "D"),
("dichte", "D"),
("viskositaet", "V"),
("waermeleitfaehigkeit", "L"),
("waermekapazitaet", "CP0MASS"),
("molemass", "molemass"),
(
"molar_gas_constant",
"gas_constant",
),
]
}
for component_name in components.keys()
},
)
except ValueError:
raise
return gas
def _calculate(self, property_name):
return sum(
properties[property_name] * self.components[name] / 100
for name, properties in self.name_to_property.items()
if self.components[name] > 0
)
@property
def density(self):
return self._calculate("dichte")
Alternativ könnte ich so etwas machen:
Code: Alles auswählen
from CoolProp.CoolProp import PropsSI
class Gas:
def __init__(
self,
components,
name_to_property,
):
self.components = components
self.name_to_property = name_to_property
self.density = None
if sum(self.components.values()) != 100:
raise ValueError(
f"Components must be 100%, now -> {list(components.values())}"
)
@classmethod
def from_components(
cls,
components,
temperature,
pressure,
):
try:
gas = cls(
components,
{
component_name: {
property_name: (
PropsSI(
property_code,
"T",
temperature,
"P",
pressure * 1e5,
component_name,
)
if property_name != "normdichte"
else PropsSI("D", "T", 273, "P", 1e5, component_name)
)
for property_name, property_code in [
("normdichte", "D"),
("dichte", "D"),
("viskositaet", "V"),
("waermeleitfaehigkeit", "L"),
("waermekapazitaet", "CP0MASS"),
("molemass", "molemass"),
(
"molar_gas_constant",
"gas_constant",
),
]
}
for component_name in components.keys()
},
)
except ValueError:
raise
return gas
def _calculate(self, property_name):
return sum(
properties[property_name] * self.components[name] / 100
for name, properties in self.name_to_property.items()
if self.components[name] > 0
)
def calculate_density(self):
self.density = self._calculate("dichte")
Gibt es hier eine Alternative? Gibt es eine Fausformel, wann man `property` verwendet und wann nicht mehr und wie geht man vor, wenn man es nicht mehr verwendet?
Vielen Dank und Grüße
Dennis