bslatkin / effectivepython

Effective Python: Second Edition — Source Code and Errata for the Book
https://effectivepython.com
2.24k stars 718 forks source link

Item 3, page 9, 2nd edition: "%s" invokes `__str__` if there's `__str__` else `__repr__` #117

Open KirkSuD opened 8 months ago

KirkSuD commented 8 months ago

Item 3, page 9, 2nd edition: print('red %s' % b'blue') "This code actually invokes the __repr__ method".

I think "%s" invokes __str__ if there's __str__ else __repr__.

I tried to find online answer, docs, cpython code, and I tested on Python 3.8:

class Test:
    pass

class TestS:
    def __str__(self):
        return "S"

class TestR:
    def __repr__(self):
        return "R"

class TestSR:
    def __str__(self):
        return "S"
    def __repr__(self):
        return "R"

for t in [Test, TestS, TestR, TestSR]:
    print(t.__name__, "%s" % t(), "%r" % t(), f"{t()!s}", f"{t()!r}")

# Test <__main__.Test object at 0x...> (and 3 more...)
# TestS S <__main__.TestS object at 0x...> S <__main__.TestS object at 0x...>
# TestR R R R R
# TestSR S R S R
bslatkin commented 4 months ago

Thank you for the report! I agree this could be more clear. Also Item 75 about __repr__ could better explain how delegation to __str__ and __repr__ works.