如何检查对象的负数

时间:2017-05-20 23:42:22

标签: python python-2.7

我有一个包含两个微分方程的值的对象。

例如:

#create equation object
class EquationValues(object):
    x         = 0
    y         = 0
    xMin      = 0
    xMax      = 0
    yMin      = 0
    yMax      = 0
    deltaTime = 0

# Class constructor/initilizer
    def __init__(self, x, y, xMin, xMax, yMin, yMax, deltaTime):
        self.x         = x
        self.y         = y
        self.xMin      = xMin
        self.xMax      = xMax
        self.yMin      = yMin
        self.yMax      = yMax
        self.deltaTime = deltaTime

def make_equationValues(x, y, xMin, xMax, yMin, yMax, deltaTime):
    equationValues = EquationValues(x, y, xMin, xMax, yMin, yMax, deltaTime)
    return equationValues

with open ('inputs.csv', 'r') as f:
    reader   = csv.reader(f, delimiter = ',')
    data     = list(reader)
    rowCount = len(data)

while x < rowCount:

    try:
        # Set variables and make sure they are the right format
        x         = float(data[x][0])
        y         = float(data[x][1])
        xMin      = float(data[x][2])
        xMax      = float(data[x][3])
        yMin      = float(data[x][4])
        yMax      = float(data[x][5])
        deltaTime = float(data[x][6])

        # Check for negative input, if negative throw value error
        if (x < 0) or (y < 0) or (xMin < 0) or (xMax < 0) or (yMin < 0) or ( yMax < 0) or (deltaTime < 0):
            raise ValueError

如何有效地检查负数的所有值?

目前,我可以通过在try / except

中使用if语句来实现

例如:

if (x < 0) or (y < 0) or (xMin < 0) or (etc):
    raise ValueError

这似乎不是最好的方法。有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

如果您的代码确实有效(如果这些属性属性,它将不起作用),您可以像这样重写它:

if any(var < 0 for var in (x, y, xMin, xMax, yMin, yMax, deltaTime)):
    raise ValueError

由于您要检查的变量只是一组名称,因此您无法做更多事情。如果它们是列表,字典或NamedTuple等,那么还有更多的改进空间。

如果检查应该在make_equationValues()进行(但为什么你没有把检查放在构造函数中?)并且你有很多比你表明,你可以这样简化检查:

def make_equationValues(*args):
    if any(var < 0 for var in args):
        raise ValueError

    return EquationValues(*args)

但是我不建议这样做,因为你的函数不再有参数签名,这使得它容易出错且难以维护。

答案 1 :(得分:1)

您可以使用any语句检查其中是否有任何一项是否为负。

class EquationValues(object):
    def __init__(self, x, y, xMin, xMax, yMin, yMax, deltaTime):    
        self.x         = x
        self.y         = y
        self.xMin      = xMin
        self.xMax      = xMax
        self.yMin      = yMin
        self.yMax      = yMax
        self.deltaTime = deltaTime

        negatives = any(v for v in {x,y,xMin,xMax,yMin,yMax,deltaTime} if v < 0)
        if negatives:
            raise ValueError("One variable is negative")

EquationValues(0,0,0,0,0,0,-1) 
# ValueError: "One variable is negative"

您还可以使用locals()获取当前本地范围变量的字典。

class EquationValues(object):
    def __init__(self, x, y, xMin, xMax, yMin, yMax, deltaTime):    
        self.x         = x
        self.y         = y
        self.xMin      = xMin
        self.xMax      = xMax
        self.yMin      = yMin
        self.yMax      = yMax
        self.deltaTime = deltaTime

        if [v for v in locals().values() if isinstance(v, int) if v < 0]:
            raise ValueError("One variable is negative")

EquationValues(0,0,0,0,0,0,-1) 
# ValueError: "One variable is negative"

答案 2 :(得分:1)

此处的示例是从Python Descriptors Demystified复制的。

您应该使用描述符来存储必须约束到某些值的属性。描述符可用于防止在使用描述符类定义的任何属性上设置无效值:

from weakref import WeakKeyDictionary

class NonNegativeNumber(object):
    def __init__(self):
        self.data = WeakKeyDictionary()

    def __get__(self, obj, objtype):
        return self.data.get(obj, 0)

    def __set__(self, obj, val):
        if val < 0:
            raise ValueError('must be nonnegative value')
        self.data[obj] = val

然后您的原始课程将如下:

class EquationValues(object):
    x         = NonNegativeNumber()
    y         = NonNegativeNumber()
    xMin      = NonNegativeNumber()
    xMax      = NonNegativeNumber()
    yMin      = NonNegativeNumber()
    yMax      = NonNegativeNumber()
    deltaTime = NonNegativeNumber()

    def __init__(self, x, y, xMin, xMax, yMin, yMax, deltaTime):
        self.x = x
        self.y = y
        self.xMin = xMin
        self.xMax = xMax
        self.yMin = yMin
        self.yMax = yMax
        self.deltaTime = deltaTime