-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Add supporting code for Python Optional Arguments tutorial #702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Using Python Optional Arguments When Defining Functions | ||
|
|
||
| This folder contains accompanying code to the Real Python tutorial on [Using Python Optional Arguments When Defining Functions](https://realpython.com/python-optional-arguments/). | ||
|
|
||
| You can read each file and its comments, and run the files to see the code's output. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| """ | ||
| Demonstrates why using a mutable default (like {}) is a bad idea. | ||
|
|
||
| This mirrors the tutorial's buggy example so you can reproduce the issue. | ||
| Run this file directly to see both variables share the same underlying dict. | ||
| """ | ||
|
|
||
|
|
||
| def add_item(item_name, quantity, shopping_list={}): | ||
| # BAD: the default dict is created once and reused | ||
| if item_name in shopping_list: | ||
| shopping_list[item_name] += quantity | ||
| else: | ||
| shopping_list[item_name] = quantity | ||
| return shopping_list | ||
|
|
||
|
|
||
| clothes_shop_list = add_item("Shirt", 3) # Uses the shared default dict | ||
| electronics_store_list = add_item("USB cable", 1) # Same shared dict! | ||
|
|
||
| print("clothes_shop_list:") | ||
| for k, v in clothes_shop_list.items(): | ||
| print(f"{v}x {k}") | ||
|
|
||
| print("\nelectronics_store_list:") | ||
| for k, v in electronics_store_list.items(): | ||
| print(f"{v}x {k}") | ||
|
|
||
| print( | ||
| "\nNote how both lists contain the same combined items " | ||
| "due to the shared default." | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| """ | ||
| Optional arguments in Python — consolidated, runnable examples. | ||
|
|
||
| This module collects the tutorial's final, good-practice implementations: | ||
|
|
||
| - show_list(shopping_list, include_quantities=True) | ||
| - add_item(item_name, quantity, shopping_list=None) | ||
| - add_items_args(shopping_list, *item_names) | ||
| - add_items_kwargs(shopping_list, **things_to_buy) | ||
|
|
||
| Run the module directly to see a short demo. | ||
| """ | ||
|
|
||
|
|
||
| def show_list(shopping_list, include_quantities=True): | ||
| for item_name, quantity in shopping_list.items(): | ||
| if include_quantities: | ||
| print(f"{quantity}x {item_name}") | ||
| else: | ||
| print(item_name) | ||
| print() | ||
|
|
||
|
|
||
| def add_item(item_name, quantity, shopping_list=None): | ||
| """Add (or increment) an item in a list using the safe 'None' default.""" | ||
| if shopping_list is None: | ||
| shopping_list = {} | ||
| if item_name in shopping_list: | ||
| shopping_list[item_name] += quantity | ||
| else: | ||
| shopping_list[item_name] = quantity | ||
| return shopping_list | ||
|
|
||
|
|
||
| def add_items_args(shopping_list, *item_names): | ||
| """Add any number of item names with default quantity 1 using *args.""" | ||
| for item_name in item_names: | ||
| if item_name in shopping_list: | ||
| shopping_list[item_name] += 1 | ||
| else: | ||
| shopping_list[item_name] = 1 | ||
| return shopping_list | ||
|
|
||
|
|
||
| def add_items_kwargs(shopping_list, **things_to_buy): | ||
| """Add any number of items with explicit quantities using **kwargs.""" | ||
| for item_name, quantity in things_to_buy.items(): | ||
| if item_name in shopping_list: | ||
| shopping_list[item_name] += quantity | ||
| else: | ||
| shopping_list[item_name] = quantity | ||
| return shopping_list | ||
|
|
||
|
|
||
| # --- Using required + optional parameters (safe default pattern) --- | ||
| hardware_store_list = {} | ||
| hardware_store_list = add_item("Nails", 1, hardware_store_list) | ||
| hardware_store_list = add_item("Screwdriver", 1, hardware_store_list) | ||
| hardware_store_list = add_item("Glue", 3, hardware_store_list) | ||
|
|
||
| supermarket_list = {} | ||
| supermarket_list = add_item("Bread", 1, supermarket_list) | ||
| supermarket_list = add_item("Milk", 2, supermarket_list) | ||
|
|
||
| show_list(hardware_store_list) # With quantities | ||
| show_list(supermarket_list, False) # Names only | ||
|
|
||
| # Create new lists on the fly by omitting shopping_list | ||
| clothes_shop_list = add_item( | ||
| "Shirt", 3 | ||
| ) # New dict created inside the function | ||
| electronics_store_list = add_item("USB cable", 1) # New dict created again | ||
| show_list(clothes_shop_list) | ||
| show_list(electronics_store_list) | ||
|
|
||
| # --- Using *args to add many items at once (defaults quantity to 1) --- | ||
| multi_add_list = {} | ||
| multi_add_list = add_items_args( | ||
| multi_add_list, "Coffee", "Tea", "Cake", "Bread" | ||
| ) | ||
| show_list(multi_add_list) | ||
|
|
||
| # --- Using **kwargs to add items with explicit quantities --- | ||
| kw_list = {} | ||
| kw_list = add_items_kwargs(kw_list, coffee=1, tea=2, cake=1, bread=3) | ||
| show_list(kw_list) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| """ | ||
| Unpacking operator demo to support the *args discussion. | ||
| """ | ||
|
|
||
| some_items = ["Coffee", "Tea", "Cake", "Bread"] | ||
|
|
||
| print("Passing the list as a single argument:") | ||
| print(some_items) # -> ['Coffee', 'Tea', 'Cake', 'Bread'] | ||
|
|
||
| print("\nUnpacking the list with *some_items:") | ||
| print(*some_items) # -> Coffee Tea Cake Bread |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 Technical Recommendation
The name
shopping_listmay imply Python'slistdata structure, while we actually use the variable to store a Python dictionary. How about renaming this variable toshopping_itemsoritem_quantitiesinstead?