This recipe builds on two previously posted recipes for a null or dummy object by modifying a few methods (e.g. as in SQL, Null == Null
is Null, not True), supporting most (all?) special methods (e.g. int(Null)) and providing correct pickling/unpickling.
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | __all__ = ['Null']
class NullType(object):
'''An SQL-like Null object: allows most (if not all) operations on it to succeed.
>>> repr(Null)
'(Null)'
>>> Null(3,x=3)
(Null)
>>> [Null==Null, Null!=None, Null<Null, Null>=3]
[(Null), (Null), (Null), (Null)]
>>> [Null[3], Null.foo]
[(Null), (Null)]
>>> Null[4] = 3
>>> del Null['bar']
>>> 2.5*Null + 3
(Null)
>>> [4 not in Null, 'all' in Null]
[True, False]
>>> list(Null)
[]
>>> bool(Null)
False
>>> len(Null)
0
>>> [int(Null), long(Null), float(Null), complex(Null)]
[0, 0, 0.0, 0j]
>>> [oct(Null), hex(Null)]
['(Null)', '(Null)']
>>> type(Null)() is Null
True
>>> from pickle import dumps, loads
>>> loads(dumps(Null)) is Null
True
'''
__singleton = None
def __new__(cls, *args, **kwds):
assert __name__ == '__main__', __name__
if cls.__singleton is None:
cls.__singleton = super(NullType,cls).__new__(cls)
return cls.__singleton
def __len__(self): return 0
def __iter__(self): return; yield
def __nonzero__ (self): return False
def __contains__(self, item): return False
def __repr__(self): return '(Null)'
def __reduce__(self): return (type(self), ())
__oct__ = __hex__ = __repr__
__int__ = __long__ = __len__
def __float__(self): return 0.0
def __call__(self, *args, **kwds): return self
__getitem__ = __getattr__ = __setitem__ = __setattr__ = __delitem__ = \
__delattr__ = __eq__ = __ne__ = __gt__ = __ge__ = __lt__ = __le__ = \
__neg__ = __pos__ = __abs__ = __invert__ = __add__ = __sub__ = \
__mul__ = __div__ = __truediv__ = __floordiv__ = __mod__ = \
__divmod__ = __pow__ = __lshift__ = __rshift__ = __and__ = __or__ = \
__xor__ = __radd__ = __rsub__ = __rmul__ = __rdiv__ = __rtruediv__ = \
__rfloordiv__ = __rmod__ = __rdivmod__ = __rpow__ = __rlshift__ = \
__rrshift__ = __rand__ = __ror__ = __rxor__ = __call__
Null = NullType()
if __name__ == '__main__':
from doctest import testmod
testmod()
|
Line 38 makes no sense to me. Why would you check if __name__ was __main__?
Also, there's not really any reason to use name mangling for the 'singleton' attribute. '_singleton' works just fine.