为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Python 中创建有界 int?

如何在 Python 中创建有界 int?

至尊宝的传说 2022-03-09 21:05:21
我想创建一个从 子类化的类int,但设置它可以是多少数字的下限和上限。例如,如果下限是2,那么a = MyClass(1)应该引发异常。我正在苦苦挣扎,因为int它似乎没有__init__功能,所以我不确定如何从中继承,我的尝试给了我错误。我该怎么做呢?
查看完整描述

2 回答

?
慕尼黑5688855

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


查看完整回答
反对 回复 2022-03-09
?
哈士奇WWW

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.


查看完整回答
反对 回复 2022-03-09
  • 2 回答
  • 0 关注
  • 124 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信