Python Forum
Why can't I explicitly call __bool__() on sequence type?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why can't I explicitly call __bool__() on sequence type?
#1
In this code, if foo: python will call foo.__bool__() implicitly to get the boolean value of foo. Which is why the following code segments work,
if 't': print("T") 
if [1]: print("T")
But I wanted to check if I can call the __bool__() method myself like the following;
't'.__bool__() # AttributeError: 'str' object has no attribute '__bool__'
[1].__bool__() # AttributeError: 'list' object has no attribute '__bool__'
As you can see it do not work, and in both cases I get AttributeError.

If __bool__() can be called implicitly in a if statement, why can I not call it explicitly?
Reply
#2
Both str and list don't have __bool__ defined and [I guess] they are evaluated in boolean context by using __len__

Quote:object.__bool__(self)

Called to implement truth value testing and the built-in operation bool(); should return False or True. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.
>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> 
quazirfan likes this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
I don't think str has a __bool__ method. I looked around for a while and I can't find it anywhere (as expected). I think bool() may have tests for some standard types (int, str, list, set...) built into the function and __bool__ is meant as a way to override the default assessment.
Reply
#4
Thanks. That cleared it up.

(Aug-10-2021, 08:21 PM)buran Wrote: If a class defines neither __len__() nor __bool__(), all its instances are considered true.

Here if str: print("True") # True - I am passing the name of the class, not an instance, but it still works.

Why is that?
Reply
#5
you understand that each class is instance of class type, right?

>>> type(str)
<class 'type'>
>>> dir(type)
['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__dir__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__prepare__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__text_signature__', '__weakrefoffset__', 'mro']
>>> 
Quote:object.__bool__(self)

Called to implement truth value testing and the built-in operation bool(); should return False or True. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.

Also explained in more detail

Quote:Truth Value Testing

Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below.

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. Here are most of the built-in objects considered false:
  • constants defined to be false: None and False.
  • zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • empty sequences and collections: '', (), [], {}, set(), range(0)

Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated. (Important exception: the Boolean operations or and and always return one of their operands.)
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
(Aug-11-2021, 04:09 AM)buran Wrote: you understand that each class is instance of class type, right?

No I didn't. Thanks! I am following a book that hasn't talked about it yet. As I am reading, I usually stop and experiment with the things I have learned, and hence the tsunami of questions.

Thanks for your answers so far!
Reply
#7
Check my updated answer, I added a link with some more details
quazirfan likes this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
(Aug-11-2021, 04:14 AM)buran Wrote: you understand that each class is instance of class type, right?

I come from Java background where every class implicitly inherits from object class. I was under the assumption it is the same with python. Then why type(str) do not return object?
Reply
#9
Classes are definitions of types, so the type of a class is "type". But this has nothing to do with inheritance.
class A():
    pass

class B(A):
    pass

class C(B):
    pass

c = C()
print(type(c))
print(type(C))
print(C.__base__)
print(A.__base__)
Output:
<class '__main__.C'> <class 'type'> <class '__main__.B'> <class 'object'>
The type of the object "c" is the class "C". The type of the class "C" is type. The superclass, or base class of "C" is "B". Oh, and the base class of "A" is object.

Think of the type of an object as the the thing that defines how the object works. The type of "hello" is class str, because the class str defines what you can do with 'hello'. It knows how to do things like find() and upper(). The type of str is type, because str is a class, and type defines how classes work. Type knows how to get the base class of a class or get the mro (method resolution order).
quazirfan likes this post
Reply
#10
@deanhystad Thanks, that cleared it up a bit.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Error : "can't multiply sequence by non-int of type 'float' " Ala 3 3,099 Apr-13-2021, 10:33 AM
Last Post: deanhystad
  TypeError: can't multiply sequence by non-int of type 'float' DimosG 3 3,377 Apr-04-2020, 05:16 AM
Last Post: michael1789
  TypeError: can't multiply sequence by non-int of type 'str' emmapaw24 2 2,509 Feb-03-2020, 05:50 PM
Last Post: michael1789
  Type hinting - return type based on parameter micseydel 2 2,508 Jan-14-2020, 01:20 AM
Last Post: micseydel
  Binding not explicitly declared happening karkas 4 2,885 Aug-05-2019, 05:09 PM
Last Post: karkas
  TypeError: can't multiply sequence by non-int of type 'str' rregorr 2 2,461 Jun-28-2019, 04:43 PM
Last Post: Yoriz
  TypeError: can't multiply sequence by non-int of type 'str' pythonnoob1234 4 4,303 May-21-2018, 06:12 PM
Last Post: wavic
  What do you call this type of parameter? league55 2 2,750 Feb-17-2018, 03:55 AM
Last Post: league55
  Cant multiply sequence by non-int type 'str' foxtreat 6 7,058 Apr-24-2017, 05:28 PM
Last Post: foxtreat

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020