In python it is valid to make a construction like:
def a():
return 0
if a:
print "Function object was considered True"
else:
print "Function object was considered False"
I wish to ask what is the logic that a function pointer is evaluated to True.
Why was this kind of construction inserted in the language?
4 Answers 4
A lot of things evaluate to True in Python. From the documentation on Boolean operators:
In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false:
False,None, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true.
Functions in Python, like so many things, are objects, and not empty. Thus, in a boolean context, they evaluate to True.
1 Comment
The rules for evaluating "truthiness" are in the Python documentation chapter on Truth Value Testing.
Note in particular that
All other values are considered true — so objects of many types are always true.
In conclusion; function objects are always true.
Comments
A list of objects that are False in python:
None[]{}empty setempty frozensetFalse00.00L0j- empty
defaultdict Classesthat have implemented__nonzero__()method and that returns a falsy value otherwise__len__()is called. In python 3x__bool__()replaced__nonzero__().
2 Comments
__nonzero__() method returns False.__len__() as it is evaluated when there is no __nonzero__() defined. Also note that __bool__() replaces __nonzero__() for Python 3.xIn the Truth Value Testing that @Magnus Hoff linked to, I found the most instructive statement to be:
By default, an object is considered true unless its class defines either a _bool_() method that returns False or a _len_() method that returns zero, when called with the object.
I tried defining my own classes, and it seems like _bool_() takes priority over _len_(), which makes sense:
class Falsish(object):
def __init__(self):
self.val = "False, even though len(self) > 0"
def __bool__(self):
return False
def __len__(self):
return 2
class StillFalsish(object):
def __init__(self):
self.val = "False, even though len(self) > 0"
def __len__(self):
return 2
def __bool__(self):
return False
class Truish(object):
def __init__(self):
self.val = "True, even though len(self) = 0"
def __bool__(self):
return True
def __len__(self):
return 0
class StillTruish(object):
def __init__(self):
self.val = "True, even though len(self) = 0"
def __len__(self):
return 0
def __bool__(self):
return True
class NowFalsish(object):
def __init__(self):
self.val = "False, with no __bool__(), since len(self) = 0"
def __len__(self):
return 0
class NowTruish(object):
def __init__(self):
self.val = "True, with no __bool__(), since len(self) > 0"
def __len__(self):
return 2
class EvenThisIsTruish(object):
pass
mybool1 = Falsish()
mybool2 = StillFalsish()
mybool3 = Truish()
mybool4 = StillTruish()
mybool5 = NowFalsish()
mybool6 = NowTruish()
mybool7 = EvenThisIsTruish()
if mybool1: print("mybool1 is true")
if mybool2: print("mybool2 is true")
if mybool3: print("mybool3 is true")
if mybool4: print("mybool4 is true")
if mybool5: print("mybool5 is true")
if mybool6: print("mybool6 is true")
if mybool7: print("mybool7 is true")
The output of the above code is:
mybool3 is true
mybool4 is true
mybool6 is true
mybool7 is true
adefined anywhere else?