值从不低于z

2024-09-27 21:29:04 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有可能将一个数值赋给一个变量,使其限定在某个范围内?更具体地说,我想要一个永远不能低于零的变量,因为如果即将发生,就会引发一个异常。在

想象中的例子:

>>> var = AlwaysPositive(0)
>>> print var 
0
>>> var += 3
>>> print var 
3
>>> var -= 4 
Traceback (most recent call last):   
   File "<stdin>", line 1, in <module> 
AlwaysPositiveError: dropping AlwaysPositive integer below zero

我问这个问题是因为我正在调试我正在编写的游戏。在人类含蓄理解的地方,你手上永远不会有-1卡片,而电脑则不会。我可以制作一些函数来检查游戏中使用的所有值,并在整个脚本的多个位置调用这些函数,看看是否出现任何奇怪的值。但我想知道有没有更简单的方法?在


Tags: 函数游戏mostvarstdincall例子file
2条回答

您可以从int子类化您自己的数据类型,并为其提供a bunch of magic methods重载所需的运算符。在

class Alwayspositive(int):
    def __init__(self, *args, **kwargs):
        super(Alwayspositive, self).__init__(*args, **kwargs)

    def __neg__(self):
        raise AlwayspositiveError()

    def __sub__(self, other):
        result = super(Alwayspositive, self).__sub__(other)
        if result < 0:
            raise AlwayspositiveError()
        return result

等等。要使这样的类安全,需要做大量的工作和调试,但它允许您调试代码,只需在调试模式和发布模式之间稍作更改。在

如果您真的需要,子类化int可能是最好的方法,但是到目前为止显示的实现还很幼稚。我会这样做:

class NegativeValueError(ValueError):
    pass


class PositiveInteger(int):

    def __new__(cls, value, base=10):
        if isinstance(value, basestring):
            inst = int.__new__(cls, value, base)
        else:
            inst = int.__new__(cls, value)
        if inst < 0:
            raise NegativeValueError()
        return inst

    def __repr__(self):
        return "PositiveInteger({})".format(int.__repr__(self))

    def __add__(self, other):
        return PositiveInteger(int.__add__(self, other))

    # ... implement other numeric type methods (__sub__, __mul__, etc.)

这允许您构造PositiveInteger,就像普通的int

^{pr2}$

有关需要实现的方法的详细信息,请参见the datamodel docs on numeric type emulation。注意,在大多数方法中,您不需要显式地检查负数,因为当您return PositiveInteger(...)__new__将为您检查。使用中:

>>> i = PositiveInteger(5)
>>> i + 3
PositiveInteger(8)

或者,如果这些非负整数将是类的属性,则可以使用descriptor protocol强制使用正值,例如:

class PositiveIntegerAttribute(object):

    def __init__(self, name):
        self.name = name

    def __get__(self, obj, typ=None):
        return getattr(obj, self.name)

    def __set__(self, obj, val):
        if not isinstance(val, (int, long)):
            raise TypeError()
        if val < 0:
            raise NegativeValueError()
        setattr(obj, self.name, val)

    def __delete__(self, obj):
        delattr(obj, self.name)

然后,您可以按如下方式使用:

>>> class Test(object):
    foo = PositiveIntegerAttribute('_foo')


>>> t = Test()
>>> t.foo = 1
>>> t.foo = -1

Traceback (most recent call last):
  File "<pyshell#34>", line 1, in <module>
    t.foo = -1
  File "<pyshell#28>", line 13, in __set__
    raise NegativeValueError()
NegativeValueError
>>> t.foo += 3
>>> t.foo
4
>>> t.foo -= 5

Traceback (most recent call last):
  File "<pyshell#37>", line 1, in <module>
    t.foo -= 5
  File "<pyshell#28>", line 13, in __set__
    raise NegativeValueError()
NegativeValueError

相关问题 更多 >

    热门问题