如何优化含有大量常量的代码?
这里有一段代码,用来做一些数学计算。这段代码不仅计算数值,还检查这些数值是否在一个可以接受的范围内。为了存储这个范围,代码中使用了类里的常量,但这样会导致常量的数量变得很多。有没有办法来优化一下这个情况呢?
from dataclasses import dataclass
from enum import Enum
class RecommendedNumberInputHoles(Enum):
MAX_NUMBER_INPUT_HOLES = 6
MIN_NUMBER_INPUT_HOLES = 2
class RecommendedDiameterRange(Enum):
MAX_RECOMMENDED_DIAMETER = 2.5
MIN_RECOMMENDED_DIAMETER = 0.5
class RelativeLength(Enum):
MAX_RELATIVE_LENGTH = 6.0
MIN_RELATIVE_LENGTH = 1.5
@dataclass(frozen=True, slots=True)
class CentrifugalLiquidInjector:
outer_diameter_injector: float
side_wall_thickness_injector: float
number_input_tangential_holes: float
diameter_input_tangential_holes: float
length_input_tangential_holes: float
relative_length_twisting_chamber: float
def __post_init__(self):
if not (RecommendedNumberInputHoles.MIN_NUMBER_INPUT_HOLES.value >= self.number_input_tangential_holes <=
RecommendedDiameterRange.MAX_RECOMMENDED_DIAMETER.value):
raise ValueError(f"Значение {self.number_input_tangential_holes} количества входных тангенциальных"
f"отверстий не входит в рекомендуемый диапазон"
f"[{RecommendedNumberInputHoles.MIN_NUMBER_INPUT_HOLES.value}..."
f"{RecommendedDiameterRange.MAX_RECOMMENDED_DIAMETER.value}]")
if not (RecommendedDiameterRange.MIN_RECOMMENDED_DIAMETER.value >= self.diameter_input_tangential_holes <=
RecommendedDiameterRange.MAX_RECOMMENDED_DIAMETER.value):
raise ValueError(f"Значение {self.diameter_input_tangential_holes} диаметров входных тангенциальных"
f"отверстий не входит в рекомендуемый диапазон"
f"[{RecommendedDiameterRange.MIN_RECOMMENDED_DIAMETER.value}..."
f"{RecommendedDiameterRange.MAX_RECOMMENDED_DIAMETER.value}]")
@property
def diameter_twisting_chamber_injector(self) -> float:
return self.outer_diameter_injector - 2 * self.side_wall_thickness_injector
@property
def relative_length_tangential_hole(self) -> float:
value_relative_length = self.length_input_tangential_holes / self.diameter_input_tangential_holes
if not(RelativeLength.MIN_RELATIVE_LENGTH.value >= value_relative_length <=
RelativeLength.MAX_RELATIVE_LENGTH.value):
raise ValueError(f"Значение {value_relative_length} относительной длины входного тангенциального отверстия"
f"не входит в допустимый диапазон [{RelativeLength.MIN_RELATIVE_LENGTH.value}..."
f"{RelativeLength.MAX_RELATIVE_LENGTH.value}]")
else:
return value_relative_length
2 个回答
0
如果不需要使用枚举(Enums),你可以把所有常量放在一个MappingProxyType里。
from types import MappingProxyType
const: MappingProxyType = MappingProxyType({"MAX_NUM_IN_HOLES" = 6, "MIN_NUM_IN_HOLES" = 2, "MAX_REC_DIAMETER" = 2.5, "MIN_REC_DIAMETER" = 0.5, "MAX_REL_LENGTH" = 6.0, "MIN_REL_LENGTH" = 1.5})
根据Python文档的说明:[MappingProxyType是一个] "只读的映射代理。它提供了一个动态视图,能反映映射中条目的变化,也就是说,当映射发生变化时,这个视图会显示这些变化。”
它的工作方式就像一个简单的Python字典(dict),你可以通过索引来访问它的元素。如果你不保留对原始字典的引用,它就是不可变的。
1
如果你一定要用
Enum
这种方式,建议你使用IntEnum
,因为IntEnum
的值是整数,这样你就不用在每次使用的时候加上.value
了。如果你想检查某个值是否在一个范围内,Python里比较常用的方法就是用
in
这个操作符。所以你可以考虑添加一个自定义的范围类,这样就能像这样操作(内置的range
只能处理整数):
class AcceptableRange:
def __init__(self, min, max):
self.min = min
self.max = max
def __contains__(self, val):
"""Return true if the value is within the acceptable range of values"""
return self.min <= val <= self.max
def __repr__(self):
"""Format the range for e.g. pasting into error messages"""
return f"[{self.min}...{self.max}]"
# then use like so:
RelativeLengthRange = AcceptableRange(1.5, 6.0)
...
# in property relative_length_tangential_hole()
if value_relative_length not in RelativeLengthRange:
raise ValueError(f"Значение {value_relative_length} относительной длины входного тангенциального отверстия " # (nitpick: add space)
f"не входит в допустимый диапазон {RelativeLengthRange!r}")
# rest of function