2 回答
TA贡献1848条经验 获得超2个赞
这是马上的,没有处理很多错误。
class boundedInt:
def __init__(self, lower, upper):
self.x = None
if (lower <= upper):
self.lower = lower
self.upper = upper
else:
raise ValueError("Lower Bound must be lesser than Upper Bound".format())
def assign(self, x):
if (x>= self.lower and x<=self.upper):
self.x = x
return self.x
else:
raise ValueError("Not in bounds")
myInt = boundedInt(15,20) # create object myInt
f = myInt.assign(17) # assigns value to a variable
TA贡献1799条经验 获得超6个赞
尝试这个。它应该适用于ints 和floats:
def BoundedNumber(number_class):
def BoundedNumberClassCreator(class_name, lower_bound, upper_bound):
if upper_bound and lower_bound and upper_bound < lower_bound:
raise ValueError(f"Upper bound {upper_bound} is lower than the lower bound {lower_bound}")
def new(cls, number):
if lower_bound and number < lower_bound:
raise ValueError(f"{number} is below the lower bound of {lower_bound} for this class")
if upper_bound and upper_bound < number:
raise ValueError(f"{number} is above the upper bound of {upper_bound} for this class")
return number_class(number)
return type(class_name, (number_class,),
{"__new__": new,
"__doc__": f"Class that acts like `{number_class.__name__}` but has an inclusive lower bound of {lower_bound} and an inclusive upper bound of {upper_bound}",
"lower_bound": lower_bound,
"upper_bound": upper_bound})
return BoundedNumberClassCreator
BoundedInt = BoundedNumber(int)
BoundedFloat = BoundedNumber(float)
if __name__ == "__main__":
IntBetween50And150 = BoundedInt('IntBetween50And150', 50, 150)
print(IntBetween50And150(100) == 100) # True
try:
IntBetween50And150(200)
except ValueError as e:
print(f"Caught the ValueError: {e}") # Caught the value error: 200 is above the upper bound of 150 for this class
print(IntBetween50And150(50.5)) # 50
print(IntBetween50And150.__doc__) # Class that acts like `int` but has an inclusive lower bound of 50 and an inclusive upper bound of 150
子类化的难点int在于它没有__init__函数。相反,您必须使用该__new__功能。
该类BoundedNumber负责这一点,定义了一个__new__函数,该函数既通过调用(or ) 运行int(or float)函数,又在执行此操作之前运行自己的边界检查。__new__intfloat
由于我们想动态创建一个新类,我们将不得不使用该type函数。这将允许我们在运行时创建一个具有我们想要的任何边界的新类。
从技术上讲,要回答您的问题,您只需要在BoundedNumberClassCreator使用int的任何地方加上 with number_class,但由于它也适用于floats,我想我会封装它以减少重复代码。
这个解决方案的一件奇怪的事情是如果你ZeroToOne = BoundedInt('ZeroToOne', 0, 1)然后创建i = ZeroToOne(1.1)它会抛出一个错误,即使int(1.1)它在指定的范围内。如果你不喜欢这个功能,你可以new在BoundedNumberClassCreator.
添加回答
举报