Reputation: 723
In Python 2.7:
Expression 1 (fine):
>>> 2 * None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
Expression 2 (fine):
>>> None is None
True
Expression 3 (bad):
>>> 2 < None
False
Expression 4 (bad):
>>> None<None
False
Expression 5 (bad):
>>> None==None
True
I want to somehow force expressions 3, 4 and 5 to throw TypeError (same as in expression 1).
Python 3.4 is nearly there - only expression 5 returns True.
I need it in 2.7.
My use case (if someone interested):
I'v made application that evaluates some expressions (example):
d = a+b
e = int(a>b)
f = a if a<b else b if b<c else c
Expressions are based on values (a, b and c) which comes from deserialized json. Most of the time values (a, b and c) are integers, but sometimes (when value is missing) it is None. When value is missing and is used in some expressions then expression should return None (I was thinking about catching TypeError exception).
In case when a=None, b=1, c=2, exptected result is: d=None, e=None, f=None.
In case when a=1, b=2, c=None, expected result is: d=3, e=0, f=1
Upvotes: 2
Views: 285
Reputation: 180441
You can use issinstance:
from numbers import Number
def pre(a, b, c):
if not isinstance(a, Number) or not isinstance(b, Number):
return None, None, None
if not isinstance(c, Number):
return a + b, a > b, a if a < b else b
return a + b, a > b, a if a < b else b if b < c else c
If any number in a calculation is None you return all Nones, if c is None you return your calculations excluding the if b < c else c and if they are all numbers then return all the expressions:
In [53]: pre(None,1,2)
Out[53]: (None, None, None)
In [54]: pre(1,2,None)
Out[54]: (3, False, 1)
In [55]: pre(None,None,None)
Out[55]: (None, None, None)
In [56]: pre(3,4,5)
Out[56]: (7, False, 3)
Upvotes: 0
Reputation: 229391
You can't change the behavior of None
. However, you can implement your own type which has the behavior you want. As a starting point:
class CalcNum(object):
def __init__(self, value):
self.value = value
def __add__(self, o):
return CalcNum(self.value + o.value)
def __lt__(self, o):
if self.value is None or o.value is None:
# Pick one:
# return CalcNum(None)
raise TypeError("Can't compare Nones")
return CalcNum(self.value < o.value)
Upvotes: 1