扩展Python的int类型以仅接受特定范围内的值

5 投票
4 回答
2859 浏览
提问于 2025-04-15 21:35

我想创建一个自定义的数据类型,它的表现方式基本上和普通的 int 一样,但它的值必须限制在一个特定的范围内。我想我需要某种工厂函数,但我不知道该怎么做。

myType = MyCustomInt(minimum=7, maximum=49, default=10)
i = myType(16)    # OK
i = myType(52)    # raises ValueError
i = myType()      # i == 10

positiveInt = MyCustomInt(minimum=1)     # no maximum restriction
negativeInt = MyCustomInt(maximum=-1)    # no minimum restriction
nonsensicalInt = MyCustomInt()           # well, the same as an ordinary int

任何提示都很感谢。谢谢!

4 个回答

1

其实不需要定义一个新的类型:

def restrict_range(minimum=None, maximum=None, default=None, type_=int):
    def restricted(*args, **kwargs):
        if default is not None and not (args or kwargs): # no arguments supplied
            return default
        value = type_(*args, **kwargs)
        if (minimum is not None and value < minimum or 
            maximum is not None and value > maximum):
            raise ValueError
        return value
    return restricted

举个例子

restricted_int = restrict_range(7, 49, 10)

assert restricted_int("1110", 2) == 14
assert restricted_int(16) == 16
assert restricted_int() == 10
try: 
    restricted_int(52)
    assert 0
except ValueError:
    pass
1

在Python中,赋值是一个语句,而不是一个表达式。这意味着你不能在某种类型上定义赋值,因为赋值会完全重新绑定这个名字。你能做的最好的办法是定义一个 set() 方法,这个方法接受你想要的值。这样的话,你可以创建一个“普通”的类来处理验证。

6

使用 __new__ 来重写不可变类型的构造过程:

def makeLimitedInt(minimum, maximum, default):
    class LimitedInt(int):
        def __new__(cls, x= default, *args, **kwargs):
            instance= int.__new__(cls, x, *args, **kwargs)
            if not minimum<=instance<=maximum:
                raise ValueError('Value outside LimitedInt range')
            return instance
    return LimitedInt

撰写回答