|
398 | 398 | "if not isinstance(dog.age, int):\n",
|
399 | 399 | " raise ValueError(\"Dog's age must be an integer.\")"
|
400 | 400 | ]
|
| 401 | + }, |
| 402 | + { |
| 403 | + "cell_type": "markdown", |
| 404 | + "id": "ec7e1d48", |
| 405 | + "metadata": {}, |
| 406 | + "source": [ |
| 407 | + "### Python Best Practices: Using default_factory for Mutable Defaults" |
| 408 | + ] |
| 409 | + }, |
| 410 | + { |
| 411 | + "cell_type": "markdown", |
| 412 | + "id": "feb1a7c8-abb3-4972-b3c1-e538ca3cbe22", |
| 413 | + "metadata": {}, |
| 414 | + "source": [ |
| 415 | + "When defining classes in Python, using mutable default values for instance variables can lead to unexpected behavior." |
| 416 | + ] |
| 417 | + }, |
| 418 | + { |
| 419 | + "cell_type": "markdown", |
| 420 | + "id": "765adba5-1145-4cd8-b714-c7c88424e47a", |
| 421 | + "metadata": {}, |
| 422 | + "source": [ |
| 423 | + "For example, if you use a list as a default value in a class's `__init__` method, all instances of the class will share the same list object:" |
| 424 | + ] |
| 425 | + }, |
| 426 | + { |
| 427 | + "cell_type": "code", |
| 428 | + "execution_count": 8, |
| 429 | + "id": "2790fc25-56ff-4797-953b-fdbf2608a87e", |
| 430 | + "metadata": {}, |
| 431 | + "outputs": [ |
| 432 | + { |
| 433 | + "name": "stdout", |
| 434 | + "output_type": "stream", |
| 435 | + "text": [ |
| 436 | + "['Author 1']\n" |
| 437 | + ] |
| 438 | + } |
| 439 | + ], |
| 440 | + "source": [ |
| 441 | + "class Book:\n", |
| 442 | + " def __init__(self, title, authors=[]):\n", |
| 443 | + " self.title = title\n", |
| 444 | + " self.authors = authors\n", |
| 445 | + "\n", |
| 446 | + "\n", |
| 447 | + "book1 = Book(\"Book 1\")\n", |
| 448 | + "book1.authors.append(\"Author 1\")\n", |
| 449 | + "\n", |
| 450 | + "book2 = Book(\"Book 2\")\n", |
| 451 | + "print(book2.authors)" |
| 452 | + ] |
| 453 | + }, |
| 454 | + { |
| 455 | + "cell_type": "markdown", |
| 456 | + "id": "9c56cdc2-7033-4edb-b505-8b456e733c64", |
| 457 | + "metadata": {}, |
| 458 | + "source": [ |
| 459 | + "In this example, `book1` and `book2` share the same list object, which is why modifying the list in `book1` affects `book2`.\n", |
| 460 | + "\n", |
| 461 | + "To avoid this issue, you can use the `default_factory` parameter in dataclasses, which creates a new object for each instance:" |
| 462 | + ] |
| 463 | + }, |
| 464 | + { |
| 465 | + "cell_type": "code", |
| 466 | + "execution_count": 9, |
| 467 | + "id": "aa062527-c688-4200-aa8d-8b65970f4297", |
| 468 | + "metadata": {}, |
| 469 | + "outputs": [ |
| 470 | + { |
| 471 | + "name": "stdout", |
| 472 | + "output_type": "stream", |
| 473 | + "text": [ |
| 474 | + "[]\n" |
| 475 | + ] |
| 476 | + } |
| 477 | + ], |
| 478 | + "source": [ |
| 479 | + "from dataclasses import dataclass, field\n", |
| 480 | + "\n", |
| 481 | + "\n", |
| 482 | + "@dataclass\n", |
| 483 | + "class Book:\n", |
| 484 | + " title: str\n", |
| 485 | + " authors: list = field(default_factory=list)\n", |
| 486 | + "\n", |
| 487 | + "\n", |
| 488 | + "book1 = Book(\"Book 1\")\n", |
| 489 | + "book1.authors.append(\"Author 1\")\n", |
| 490 | + "\n", |
| 491 | + "book2 = Book(\"Book 2\")\n", |
| 492 | + "print(book2.authors)" |
| 493 | + ] |
| 494 | + }, |
| 495 | + { |
| 496 | + "cell_type": "markdown", |
| 497 | + "id": "8be32d8d-c083-425e-889d-0548dd4f3183", |
| 498 | + "metadata": {}, |
| 499 | + "source": [ |
| 500 | + "Now, each instance has its own separate list object, and modifying one instance's list does not affect others." |
| 501 | + ] |
401 | 502 | }
|
402 | 503 | ],
|
403 | 504 | "metadata": {
|
404 | 505 | "kernelspec": {
|
405 |
| - "display_name": "Python 3.8.9 ('venv': venv)", |
| 506 | + "display_name": "Python 3 (ipykernel)", |
406 | 507 | "language": "python",
|
407 | 508 | "name": "python3"
|
408 | 509 | },
|
|
430 | 531 | "toc_position": {},
|
431 | 532 | "toc_section_display": true,
|
432 | 533 | "toc_window_display": false
|
433 |
| - }, |
434 |
| - "vscode": { |
435 |
| - "interpreter": { |
436 |
| - "hash": "484329849bb907480cd798e750759bc6f1d66c93f9e78e7055aa0a2c2de6b47b" |
437 |
| - } |
438 | 534 | }
|
439 | 535 | },
|
440 | 536 | "nbformat": 4,
|
|
0 commit comments