Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any builtin Python value where truth evaluation is invalid?

Tags:

python

boolean

I have a set of sub-classes that should all define an attribute x that should either evaluate to True or False. In order to catch bugs when I forget to set this value in a subclass, I would like to set it in its superclass to a value for which truth evaluation results in an error. Is there any built-in value in Python with this behaviour? I sort of expected NotImplemented to have this behaviour, but it evaluates to True.

I could set it to numpy.array([0, 0]) where if x: raises ValueError, but that feels wrong. Likewise, I could define my own class where __bool__ raises an exception. But is there any built-in value appropriate for this purpose?

Other alternatives would be to set a property (abstract or not) or to not define it at all (so we get AttributeError).

like image 517
gerrit Avatar asked Nov 01 '22 18:11

gerrit


1 Answers

I recently encountered the same question, with a slightly different use case:

I had a class with a flag attribute, the value of which is passed to __init__ by the caller. Objects of the class can be created from two different versions of data, where the older version of the data does not contain the information needed for determining whether the flag should be True of False.

Setting an otherwise bool-value to None (which is the common way of representing missing data) would not work, because None happily evaluates to False.

Like you, I didn't find a satisfactory built-in solution, so I wrote one myself.

(Written for python2.7, but easy to adjust fo python3)

class NotTrueNorFalseType(object):
    """
    A singleton class whose instance can be used in place of True or False, to represent
    a value which has no true-value nor false-value, e.g. a boolean flag the value of
    which is unknown or undefined.
    """
    def __new__(cls, *args, **kwargs):
        # singleton
        try:
            obj = cls._obj
        except AttributeError:
            obj = object.__new__(cls, *args, **kwargs)
            cls._obj = obj
        return obj

    def __nonzero__(self):
        raise TypeError('%s: Value is neither True nor False' % self)

    def __repr__(self):
        return 'NotTrueNorFalse'

NotTrueNorFalse = NotTrueNorFalseType()

The design (min-)decisions in this class were inspired by the None singleton (E.g. naming the singleton instance "Foo" and the class "FooType", returning "Foo" from __repr__, raising TypeError on invalid operations).

like image 141
shx2 Avatar answered Nov 15 '22 04:11

shx2