|
2526 | 2526 | 'code': 'def label(score: int) -> str:\n return f"score={score}"\n\nprint(label("high"))', |
2527 | 2527 | 'output': 'score=high', |
2528 | 2528 | 'line': 44}]}, |
| 2529 | + {'slug': 'protocols', |
| 2530 | + 'title': 'Protocols', |
| 2531 | + 'section': 'Types', |
| 2532 | + 'summary': 'Protocol describes required behavior for structural typing.', |
| 2533 | + 'doc_url': 'https://docs.python.org/3.13/library/typing.html#typing.Protocol', |
| 2534 | + 'code': 'from typing import Protocol\n' |
| 2535 | + '\n' |
| 2536 | + 'class Greeter(Protocol):\n' |
| 2537 | + ' def greet(self) -> str:\n' |
| 2538 | + ' ...\n' |
| 2539 | + '\n' |
| 2540 | + 'class Person:\n' |
| 2541 | + ' def __init__(self, name):\n' |
| 2542 | + ' self.name = name\n' |
| 2543 | + '\n' |
| 2544 | + ' def greet(self):\n' |
| 2545 | + ' return f"hello {self.name}"\n' |
| 2546 | + '\n' |
| 2547 | + '\n' |
| 2548 | + 'def welcome(greeter: Greeter):\n' |
| 2549 | + ' print(greeter.greet())\n' |
| 2550 | + '\n' |
| 2551 | + 'welcome(Person("Ada"))\n' |
| 2552 | + 'print(Greeter.__name__)\n', |
| 2553 | + 'expected_output': 'hello Ada\nGreeter\n', |
| 2554 | + 'notes': ['Protocols are for structural typing: compatibility by shape rather than explicit inheritance.', |
| 2555 | + 'Type checkers understand protocols; normal runtime method calls still do the work.', |
| 2556 | + 'Prefer inheritance when shared implementation matters, and protocols when only required behavior ' |
| 2557 | + 'matters.'], |
| 2558 | + 'cells': [{'prose': ['A protocol names required behavior. The ellipsis marks the method body as intentionally ' |
| 2559 | + 'unspecified, similar to an interface declaration.'], |
| 2560 | + 'code': 'from typing import Protocol\n' |
| 2561 | + '\n' |
| 2562 | + 'class Greeter(Protocol):\n' |
| 2563 | + ' def greet(self) -> str:\n' |
| 2564 | + ' ...\n' |
| 2565 | + '\n' |
| 2566 | + 'print(Greeter.__name__)', |
| 2567 | + 'output': 'Greeter', |
| 2568 | + 'line': 22}, |
| 2569 | + {'prose': ['A class can satisfy the protocol without inheriting from it. `Person` has a compatible ' |
| 2570 | + '`greet()` method, so it has the right shape for static type checkers.'], |
| 2571 | + 'code': 'class Person:\n' |
| 2572 | + ' def __init__(self, name):\n' |
| 2573 | + ' self.name = name\n' |
| 2574 | + '\n' |
| 2575 | + ' def greet(self):\n' |
| 2576 | + ' return f"hello {self.name}"\n' |
| 2577 | + '\n' |
| 2578 | + 'print(Person("Ada").greet())', |
| 2579 | + 'output': 'hello Ada', |
| 2580 | + 'line': 40}, |
| 2581 | + {'prose': ['Use the protocol as an annotation at the API boundary. The function only cares that the object ' |
| 2582 | + 'can greet; it does not care about the concrete class.'], |
| 2583 | + 'code': 'def welcome(greeter: Greeter):\n print(greeter.greet())\n\nwelcome(Person("Ada"))', |
| 2584 | + 'output': 'hello Ada', |
| 2585 | + 'line': 59}]}, |
2529 | 2586 | {'slug': 'enums', |
2530 | 2587 | 'title': 'Enums', |
2531 | 2588 | 'section': 'Types', |
|
0 commit comments