Magic methods in Python are special functions with names surrounded by double underscores, like __str__ or __init__. They let objects respond to built-in operations such as printing or adding. When you create an object and use print on it, Python looks for the __str__ method to get a string to show. If __str__ is defined, it returns a friendly string. If not, Python shows a default message with the object's type and memory address. This example creates a Box object with size 5. When print(b) runs, Python calls b.__str__() and prints 'Box of size 5'. This shows how magic methods customize object behavior in Python.