keeping a variable inside a range in python
我试图为游戏pong编写一个代码,但当我试图控制桨位置的范围时,我面临一个问题,问题是:在python中,是否有一种方法可以将变量保持在某个范围内(最大值和最小值),当变量改变(将增加)时,它将停留在最大值上?在这个范围内,当这个变量减小时,它会停留在最小值上?.
我写了这段代码:
1 2 3 4 | Range = range(HALF_PAD_HEIGHT, HEIGHT - HALF_PAD_HEIGHT) if (paddle1_pos[1] in Range) and (paddle2_pos[1] in Range): paddle1_pos[1] += paddle1_vel[1] paddle2_pos[1] += paddle2_vel[1] |
当桨叶位置(桨叶1_位置[1]和桨叶2_位置[1])的值超出范围时,我无法再使用键盘(通过变量(桨叶1_级别[1]和桨叶2_值[2])更新其位置,因此,我认为可能在python中存在某种允许我更新桨叶位置的东西,当我到达一侧时,在这个范围内,它使我保持在这一边,直到我改变更新的方向。希望问题是清楚的。
谢谢
为了完整性,这里还有另一个答案,说明如何使用元类以编程方式将整数必须使用的所有算术方法添加到自定义类中。注意,不清楚在每种情况下返回一个与操作数具有相同边界的边界是否有意义。代码还与python2&3兼容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | class MetaBoundedInt(type): # int arithmetic methods that return an int _specials = ('abs add and div floordiv invert lshift mod mul neg or pos ' 'pow radd rand rdiv rfloordiv rlshift rmod rmul ror rpow ' 'rrshift rshift rsub rtruediv rxor sub truediv xor').split() _ops = set('__%s__' % name for name in _specials) def __new__(cls, name, bases, attrs): classobj = type.__new__(cls, name, bases, attrs) # create wrappers for specified arithmetic operations for name, meth in ((n, m) for n, m in vars(int).items() if n in cls._ops): setattr(classobj, name, cls._WrappedMethod(cls, meth)) return classobj class _WrappedMethod(object): def __init__(self, cls, func): self.cls, self.func = cls, func def __get__(self, obj, cls=None): def wrapper(*args, **kwargs): # convert result of calling self.func() to cls instance return cls(self.func(obj, *args, **kwargs), bounds=obj._bounds) for attr in '__module__', '__name__', '__doc__': setattr(wrapper, attr, getattr(self.func, attr, None)) return wrapper def with_metaclass(meta, *bases): """ Py 2 & 3 compatible way to specifiy a metaclass.""" return meta("NewBase", bases, {}) class BoundedInt(with_metaclass(MetaBoundedInt, int)): def __new__(cls, *args, **kwargs): lower, upper = bounds = kwargs.pop('bounds') val = int.__new__(cls, *args, **kwargs) # supports all int() args val = super(BoundedInt, cls).__new__(cls, min(max(lower, val), upper)) val._bounds = bounds return val if __name__ == '__main__': # all results should be BoundInt instances with values within bounds v = BoundedInt('64', 16, bounds=(0, 100)) # 0x64 == 100 print('type(v)={}, value={}, bounds={}'.format(type(v).__name__, v, v._bounds)) v += 10 print('type(v)={}, value={}, bounds={}'.format(type(v).__name__, v, v._bounds)) w = v + 10 print('type(w)={}, value={}, bounds={}'.format(type(w).__name__, w, w._bounds)) x = v - 110 print('type(x)={}, value={}, bounds={}'.format(type(x).__name__, x, x._bounds)) |
输出:
1 2 3 4 | type(v)=BoundedInt, value=100, bounds=(0, 100) type(v)=BoundedInt, value=100, bounds=(0, 100) type(w)=BoundedInt, value=100, bounds=(0, 100) type(x)=BoundedInt, value=0, bounds=(0, 100) |
您可以定义自己的"有界"数字类型。例如,如果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | class BoundedInt(int): def __new__(cls, *args, **kwargs): lower, upper = bounds = kwargs.pop('bounds') val = int.__new__(cls, *args, **kwargs) # supports all int() args val = lower if val < lower else upper if val > upper else val val = super(BoundedInt, cls).__new__(cls, val) val._bounds = bounds return val def __add__(self, other): return BoundedInt(int(self)+other, bounds=self._bounds) __iadd__ = __add__ def __sub__(self, other): return BoundedInt(int(self)-other, bounds=self._bounds) __isub__ = __sub__ def __mul__(self, other): return BoundedInt(int(self)*other, bounds=self._bounds) __imul__ = __mul__ # etc, etc... if __name__ == '__main__': v = BoundedInt(100, bounds=(0, 100)) print type(v), v v += 10 print type(v), v w = v + 10 print type(w), w x = v - 110 print type(x), x |
输出:
1 2 3 4 | <class '__main__.BoundedInt'> 100 <class '__main__.BoundedInt'> 100 <class '__main__.BoundedInt'> 100 <class '__main__.BoundedInt'> 0 |