Functions & Scope
*args and **kwargs
Flexible Arguments
You're writing a logging function that should accept any number of messages.
Or a config function that takes arbitrary key-value options. *args and
**kwargs let you accept variable arguments without knowing them in advance.
Accept any positional arguments
Use *args to collect extra positional arguments.
def main():
print("=== *args: Variable Positional Arguments ===\n")
# Any number of arguments
print("sum_all with different counts:")
print(f"sum_all(1, 2) = {sum_all(1, 2)}")
print(f"sum_all(1, 2, 3) = {sum_all(1, 2, 3)}")
print(f"sum_all(1, 2, 3, 4, 5) = {sum_all(1, 2, 3, 4, 5)}")
print(f"sum_all() = {sum_all()}") # Zero args OK!
print("\n=== What is *args? ===")
show_args(10, 20, 30)
print("\n=== Required + *args ===")
greet("Hello", "Alice", "Bob", "Charlie")
greet("Hi", "Dave")
print("\n=== Type Hints with *args ===")
result = concat_strings("Hello", " ", "World", "!")
print(f"concat_strings result: {result}")
def sum_all(*numbers):
"""Sum any number of values."""
total = 0
for n in numbers:
total += n
return total
def show_args(*args):
"""Show what args contains."""
print(f"args = {args}")
print(f"type(args) = {type(args).__name__}")
print(f"len(args) = {len(args)}")
def greet(greeting, *names):
"""Greet multiple people."""
for name in names:
print(f"{greeting}, {name}!")
def concat_strings(*strings: str) -> str:
"""Concatenate any number of strings (typed)."""
return "".join(strings)
if __name__ == "__main__":
main()
def main():
1#@var=default,typed2def main():3 print("=== *args: Variable Positional Arguments ===\n")4 5 # Any number of arguments #?any6 print("sum_all with different counts:")7 print(f"sum_all(1, 2) = {sum_all(1, 2)}")8 print(f"sum_all(1, 2, 3) = {sum_all(1, 2, 3)}")output=== *args: Variable Positional Arguments === sum_all with different counts:total ← 0
pass 1 of 425def sum_all(*numbers(1, 2)): #?starargs26 """Sum any number of values."""27 total→ 0 = 028 for n in numbers:All 4 passes — pass 1 is the card above pass numberstotal1 (1, 2) 0 2 (1, 2, 3) 0 3 (1, 2, 3, 4, 5) 0 4 () 0 total ← 1
pass 1 of 1027total = 028for n1 in numbers(1, 2):29 total→ 1 += n130return totalAll 10 passes — pass 1 is the card above pass nnumberstotal1 1 (1, 2) 0 → 1 2 2 (1, 2) 1 → 3 3 1 (1, 2, 3) 0 → 1 4 2 (1, 2, 3) 1 → 3 5 3 (1, 2, 3) 3 → 6 6 1 (1, 2, 3, 4, 5) 0 → 1 7 2 (1, 2, 3, 4, 5) 1 → 3 8 3 (1, 2, 3, 4, 5) 3 → 6 9 4 (1, 2, 3, 4, 5) 6 → 10 10 5 (1, 2, 3, 4, 5) 10 → 15 return total
29 total += n30return total3print(f"sum_all(1, 2) = {sum_all(1, 2)}")
6print("sum_all with different counts:")7print(f"sum_all(1, 2) = {sum_all(1, 2)}")8print(f"sum_all(1, 2, 3) = {sum_all(1, 2, 3)}")9print(f"sum_all(1, 2, 3, 4, 5) = {sum_all(1, 2, 3, 4, 5)}")outputsum_all(1, 2) = 3return total
29 total += n30return total6print(f"sum_all(1, 2, 3) = {sum_all(1, 2, 3)}")
7print(f"sum_all(1, 2) = {sum_all(1, 2)}")8print(f"sum_all(1, 2, 3) = {sum_all(1, 2, 3)}")9print(f"sum_all(1, 2, 3, 4, 5) = {sum_all(1, 2, 3, 4, 5)}")10print(f"sum_all() = {sum_all()}") # Zero args OK!outputsum_all(1, 2, 3) = 6return total
29 total += n30return total15print(f"sum_all(1, 2, 3, 4, 5) = {sum_all(1, 2, 3, 4, 5)}")
8print(f"sum_all(1, 2, 3) = {sum_all(1, 2, 3)}")9print(f"sum_all(1, 2, 3, 4, 5) = {sum_all(1, 2, 3, 4, 5)}")10print(f"sum_all() = {sum_all()}") # Zero args OK!outputsum_all(1, 2, 3, 4, 5) = 15print(f"sum_all() = {sum_all()}") # Zero args OK!
9print(f"sum_all(1, 2, 3, 4, 5) = {sum_all(1, 2, 3, 4, 5)}")10print(f"sum_all() = {sum_all()}") # Zero args OK!1112print("\n=== What is *args? ===") #?whatis13show_args(10, 20, 30)outputsum_all() = 0 === What is *args? ===def show_args(*args): #?inspect
12 print("\n=== What is *args? ===") #?whatis13 show_args(10, 20, 30)14 15 print("\n=== Required + *args ===") #?required16 greet("Hello", "Alice", "Bob", "Charlie")17 greet("Hi", "Dave")18 19 #@var=_,!20 print("\n=== Type Hints with *args ===")21 result = concat_strings("Hello", " ", "World", "!")22 print(f"concat_strings result: {result}")23 #@var=_,!2425def sum_all(*numbers): #?starargs26 """Sum any number of values."""27 total = 028 for n in numbers:29 total += n30 return total3132def show_args(*args(10, 20, 30)): #?inspect33 """Show what args contains."""34 print(f"args = {args(10, 20, 30)}")35 print(f"type(args) = {type(args(10, 20, 30)).__name__}")36 print(f"len(args) = {len(args(10, 20, 30))}")outputargs = (10, 20, 30) type(args) = tuple len(args) = 3 === Required + *args ===def greet(greeting, *names): #?mixed
pass 1 of 238def greet(greetingHello, *names('Alice', 'Bob', 'Charlie')): #?mixed39 """Greet multiple people."""40 for name in names:for name in names:
pass 1 of 439"""Greet multiple people."""40for nameAlice in names('Alice', 'Bob', 'Charlie'):41 print(f"{greetingHello}, {nameAlice}!")outputHello, Alice!All 4 passes — pass 1 is the card above pass namenamesgreetingstrings1 Alice ('Alice', 'Bob', 'Charlie') Hello — 2 Bob ('Alice', 'Bob', 'Charlie') Hello — 3 Charlie ('Alice', 'Bob', 'Charlie') Hello — 4 Dave ('Dave',) Hi ('Hello', ' ', 'World', '!') def greet(greeting, *names): #?mixed
pass 2 of 238def greet(greetingHi, *names('Dave',)): #?mixed39 """Greet multiple people."""40 for name in names:def concat_strings(*strings: str) -> str: #?typed
43#@var=_,!44def concat_strings(*strings('Hello', ' ', 'World', '!'): str) -> str: #?typed45 """Concatenate any number of strings (typed)."""46 return "".join(strings('Hello', ' ', 'World', '!'))47#@var=_,!result ← Hello World!
20 print("\n=== Type Hints with *args ===")21 result→ Hello World! = concat_strings("Hello", " ", "World", "!")22 print(f"concat_strings result: {resultHello World!}")23 #@var=_,!2425def sum_all(*numbers): #?starargs26 """Sum any number of values."""27 total = 028 for n in numbers:29 total += n30 return total3132def show_args(*args): #?inspect33 """Show what args contains."""34 print(f"args = {args}")35 print(f"type(args) = {type(args).__name__}")36 print(f"len(args) = {len(args)}")3738def greet(greeting, *names): #?mixed39 """Greet multiple people."""40 for name in names:41 print(f"{greeting}, {name}!")4243#@var=_,!44def concat_strings(*strings: str) -> str: #?typed45 """Concatenate any number of strings (typed)."""46 return "".join(strings)47#@var=_,!4849if __name__ == "__main__":50 main()51#@help anyoutputconcat_strings result: Hello World!
*args collects extra positional arguments into a tuple.
Accept any keyword arguments
Use **kwargs to collect extra keyword arguments.
def main():
print("=== **kwargs: Variable Keyword Arguments ===\n")
# Any keyword arguments
print("User profiles:")
print_info(name="Alice", age=30, city="NYC")
print()
print_info(name="Bob", occupation="Developer")
print()
print_info(username="charlie", email="c@test.com", premium=True)
print("\n=== What is **kwargs? ===")
show_kwargs(x=10, y=20, z=30)
print("\n=== Building Objects ===")
config = make_config(debug=True, timeout=30, retries=3)
print(f"Config: {config}")
print("\n=== With Validation ===")
try:
validated = create_user(name="Alice", email="alice@test.com")
print(f"Created: {validated}")
except ValueError as e:
print(f"Error: {e}")
def print_info(**kwargs):
"""Print all provided info."""
for key, value in kwargs.items():
print(f" {key}: {value}")
def show_kwargs(**kwargs):
"""Show what kwargs contains."""
print(f"kwargs = {kwargs}")
print(f"type(kwargs) = {type(kwargs).__name__}")
print(f"keys = {list(kwargs.keys())}")
def make_config(**settings):
"""Create config dict from keyword args."""
# Add defaults
config = {
'debug': False,
'timeout': 60,
'retries': 5
}
# Override with provided settings
config.update(settings)
return config
def create_user(**fields):
"""Create user with validation."""
required = ['name', 'email']
for field in required:
if field not in fields:
raise ValueError(f"Missing required field: {field}")
return fields
if __name__ == "__main__":
main()
def main():
1#@var=default,validation2def main():3 print("=== **kwargs: Variable Keyword Arguments ===\n")4 5 # Any keyword arguments #?any6 print("User profiles:")7 print_info(name="Alice", age=30, city="NYC")8 print()output=== **kwargs: Variable Keyword Arguments === User profiles:def print_info(**kwargs): #?doublestar
pass 1 of 329def print_info(**kwargs): #?doublestar30 """Print all provided info."""31 for key, value in kwargs.items():All 3 passes — pass 1 is the card above pass kwargssettingsconfig1 — — — 2 — — — 3 {'x': 10, 'y': 20, 'z': 30} {'debug': True, 'timeout': 30, 'retries': 3} {'debug': True, 'timeout': 30, 'retries': 3} → {'debug': False, 'timeout': 60, 'retries': 5} for key, value in kwargs.items():
pass 1 of 830"""Print all provided info."""31for keyname, valueAlice in kwargs{'name': 'Alice', 'age': 30, 'city': 'NYC'}.items():32 print(f" {keyname}: {valueAlice}")output name: AliceAll 8 passes — pass 1 is the card above pass keyvaluekwargssettingsconfig1 name Alice {'name': 'Alice', 'age': 30, 'city': 'NYC'} — — 2 age 30 {'name': 'Alice', 'age': 30, 'city': 'NYC'} — — 3 city NYC {'name': 'Alice', 'age': 30, 'city': 'NYC'} — — 4 name Bob {'name': 'Bob', 'occupation': 'Developer'} — — 5 occupation Developer {'name': 'Bob', 'occupation': 'Developer'} — — 6 username charlie {'username': 'charlie', 'email': 'c@test.com', 'premium': True} — — 7 email c@test.com {'username': 'charlie', 'email': 'c@test.com', 'premium': True} — — 8 premium True {'username': 'charlie', 'email': 'c@test.com', 'premium': True} {'debug': True, 'timeout': 30, 'retries': 3} {'debug': True, 'timeout': 30, 'retries': 3} → {'debug': False, 'timeout': 60, 'retries': 5} def show_kwargs(**kwargs): #?inspect
13 print("\n=== What is **kwargs? ===") #?whatis14 show_kwargs(x=10, y=20, z=30)15 16 print("\n=== Building Objects ===") #?build17 config = make_config(debug=True, timeout=30, retries=3)18 print(f"Config: {config}")19 20 #@var=_,!21 print("\n=== With Validation ===")22 try:23 validated = create_user(name="Alice", email="alice@test.com")24 print(f"Created: {validated}")25 except ValueError as e:26 print(f"Error: {e}")27 #@var=_,!2829def print_info(**kwargs): #?doublestar30 """Print all provided info."""31 for key, value in kwargs.items():32 print(f" {key}: {value}")3334def show_kwargs(**kwargs): #?inspect35 """Show what kwargs contains."""36 print(f"kwargs = {kwargs{'x': 10, 'y': 20, 'z': 30}}")37 print(f"type(kwargs) = {type(kwargs{'x': 10, 'y': 20, 'z': 30}).__name__}")38 print(f"keys = {list(kwargs{'x': 10, 'y': 20, 'z': 30}.keys())}")outputkwargs = {'x': 10, 'y': 20, 'z': 30} type(kwargs) = dict keys = ['x', 'y', 'z'] === Building Objects ===config ← {'debug': False, 'timeout': 60, 'retries': 5}
40def make_config(**settings): #?return41 """Create config dict from keyword args."""42 # Add defaults43 config→ {'debug': False, 'timeout': 60, 'retries': 5} = {44 'debug': False,45 'timeout': 60,46 'retries': 547 }48 # Override with provided settings49 config→ {'debug': True, 'timeout': 30, 'retries': 3}.update(settings{'debug': True, 'timeout': 30, 'retries': 3})50 return config{'debug': True, 'timeout': 30, 'retries': 3}config ← {'debug': True, 'timeout': 30, 'retries': 3}
16print("\n=== Building Objects ===") #?build17config→ {'debug': True, 'timeout': 30, 'retries': 3} = make_config(debug=True, timeout=30, retries=3)18print(f"Config: {config{'debug': True, 'timeout': 30, 'retries': 3}}")1920#@var=_,!21print("\n=== With Validation ===")22try:outputConfig: {'debug': True, 'timeout': 30, 'retries': 3} === With Validation ===required ← ['name', 'email']
52#@var=_,!53def create_user(**fields): #?validate54 """Create user with validation."""55 required→ ['name', 'email'] = ['name', 'email']56 for field in required:for field in required:
pass 1 of 255required = ['name', 'email']56for fieldname in required['name', 'email']:57 if field not in fields:58 raise ValueError(f"Missing required field: {field}")for field in required:
pass 2 of 255required = ['name', 'email']56for fieldemail in required['name', 'email']:57 if field not in fields:58 raise ValueError(f"Missing required field: {field}")return fields
58 raise ValueError(f"Missing required field: {field}")59 return fields{'name': 'Alice', 'email': 'alice@test.com'}60#@var=_,!validated ← {'name': 'Alice', 'email': 'alice@test.com'}
22 try:23 validated→ {'name': 'Alice', 'email': 'alice@test.com'} = create_user(name="Alice", email="alice@test.com")24 print(f"Created: {validated{'name': 'Alice', 'email': 'alice@test.com'}}")25 except ValueError as e:26 print(f"Error: {e}")27 #@var=_,!2829def print_info(**kwargs): #?doublestar30 """Print all provided info."""31 for key, value in kwargs.items():32 print(f" {key}: {value}")3334def show_kwargs(**kwargs): #?inspect35 """Show what kwargs contains."""36 print(f"kwargs = {kwargs}")37 print(f"type(kwargs) = {type(kwargs).__name__}")38 print(f"keys = {list(kwargs.keys())}")3940def make_config(**settings): #?return41 """Create config dict from keyword args."""42 # Add defaults43 config = {44 'debug': False,45 'timeout': 60,46 'retries': 547 }48 # Override with provided settings49 config.update(settings)50 return config5152#@var=_,!53def create_user(**fields): #?validate54 """Create user with validation."""55 required = ['name', 'email']56 for field in required:57 if field not in fields:58 raise ValueError(f"Missing required field: {field}")59 return fields60#@var=_,!6162if __name__ == "__main__":63 main()64#@help anyoutputCreated: {'name': 'Alice', 'email': 'alice@test.com'}
**kwargs collects extra keyword arguments into a dictionary.
Combine *args and **kwargs
Accept both kinds of variable arguments.
def main():
print("=== Combining *args and **kwargs ===\n")
# Both together
log("INFO", "User logged in", user="Alice", ip="192.168.1.1")
log("ERROR", "Connection failed", "timeout", retries=3)
log("DEBUG", "Processing") # Just message
print("\n=== Full Signature Order ===")
demonstrate_order("required", "extra1", "extra2",
kw_only="value", opt1="a", opt2="b")
print("\n=== Catch-All Function ===")
catch_all(1, 2, 3, name="test", flag=True)
def log(level, message, *tags, **metadata):
"""Log with optional tags and metadata."""
print(f"[{level}] {message}")
if tags:
print(f" Tags: {', '.join(tags)}")
if metadata:
for key, value in metadata.items():
print(f" {key}: {value}")
print()
def demonstrate_order(required, *args, kw_only, **kwargs):
"""Show the required parameter order."""
print(f"required: {required}")
print(f"*args: {args}")
print(f"kw_only: {kw_only}")
print(f"**kwargs: {kwargs}")
def catch_all(*args, **kwargs):
"""Accept literally anything."""
print(f"Positional ({len(args)}): {args}")
print(f"Keyword ({len(kwargs)}): {kwargs}")
if __name__ == "__main__":
main()
def main():
1def main():2 print("=== Combining *args and **kwargs ===\n")3 4 # Both together #?combined5 log("INFO", "User logged in", user="Alice", ip="192.168.1.1")6 log("ERROR", "Connection failed", "timeout", retries=3)output=== Combining *args and **kwargs ===def log(level, message, *tags, **metadata): #?signature
pass 1 of 316def log(levelINFO, messageUser logged in, *tags(), **metadata): #?signature17 """Log with optional tags and metadata."""18 print(f"[{levelINFO}] {messageUser logged in}")19 if tags:output[INFO] User logged inAll 3 passes — pass 1 is the card above pass levelmessagetagsmetadatarequiredargskw_onlykwargs1 INFO User logged in () {'user': 'Alice', 'ip': '192.168.1.1'} — — — — 2 ERROR Connection failed ('timeout',) {'retries': 3} — — — — 3 DEBUG Processing () — required ('extra1', 'extra2') value {'opt1': 'a', 'opt2': 'b'} if metadata:
pass 1 of 220 print(f" Tags: {', '.join(tags)}")21if metadata{'user': 'Alice', 'ip': '192.168.1.1'}:22 for key, value in metadata.items():23 print(f" {key}: {value}")for key, value in metadata.items():
pass 1 of 321if metadata:22 for keyuser, valueAlice in metadata{'user': 'Alice', 'ip': '192.168.1.1'}.items():23 print(f" {keyuser}: {valueAlice}")24print()output user: AliceAll 3 passes — pass 1 is the card above pass keyvaluemetadata1 user Alice {'user': 'Alice', 'ip': '192.168.1.1'} 2 ip 192.168.1.1 {'user': 'Alice', 'ip': '192.168.1.1'} 3 retries 3 {'retries': 3} print()
4 # Both together #?combined5 log("INFO", "User logged in", user="Alice", ip="192.168.1.1")6 log("ERROR", "Connection failed", "timeout", retries=3)7 log("DEBUG", "Processing") # Just message8 9 print("\n=== Full Signature Order ===") #?order10 demonstrate_order("required", "extra1", "extra2", 11 kw_only="value", opt1="a", opt2="b")12 13 print("\n=== Catch-All Function ===") #?catchall14 catch_all(1, 2, 3, name="test", flag=True)1516def log(level, message, *tags, **metadata): #?signature17 """Log with optional tags and metadata."""18 print(f"[{level}] {message}")19 if tags:20 print(f" Tags: {', '.join(tags)}")21 if metadata:22 for key, value in metadata.items():23 print(f" {key}: {value}")24 print()if tags:
18print(f"[{level}] {message}")19if tags('timeout',):20 print(f" Tags: {', '.join(tags('timeout',))}")21if metadata:output Tags: timeoutif metadata:
pass 2 of 220 print(f" Tags: {', '.join(tags)}")21if metadata{'retries': 3}:22 for key, value in metadata.items():23 print(f" {key}: {value}")print()
5 log("INFO", "User logged in", user="Alice", ip="192.168.1.1")6 log("ERROR", "Connection failed", "timeout", retries=3)7 log("DEBUG", "Processing") # Just message8 9 print("\n=== Full Signature Order ===") #?order10 demonstrate_order("required", "extra1", "extra2", 11 kw_only="value", opt1="a", opt2="b")12 13 print("\n=== Catch-All Function ===") #?catchall14 catch_all(1, 2, 3, name="test", flag=True)1516def log(level, message, *tags, **metadata): #?signature17 """Log with optional tags and metadata."""18 print(f"[{level}] {message}")19 if tags:20 print(f" Tags: {', '.join(tags)}")21 if metadata:22 for key, value in metadata.items():23 print(f" {key}: {value}")24 print()def demonstrate_order(required, *args, kw_only, **kwargs): #?fullorde…
9 print("\n=== Full Signature Order ===") #?order10 demonstrate_order("required", "extra1", "extra2", 11 kw_only="value", opt1="a", opt2="b")12 13 print("\n=== Catch-All Function ===") #?catchall14 catch_all(1, 2, 3, name="test", flag=True)1516def log(level, message, *tags, **metadata): #?signature17 """Log with optional tags and metadata."""18 print(f"[{level}] {message}")19 if tags:20 print(f" Tags: {', '.join(tags)}")21 if metadata:22 for key, value in metadata.items():23 print(f" {key}: {value}")24 print()2526def demonstrate_order(requiredrequired, *args('extra1', 'extra2'), kw_only, **kwargs): #?fullorder27 """Show the required parameter order."""28 print(f"required: {requiredrequired}")29 print(f"*args: {args('extra1', 'extra2')}")30 print(f"kw_only: {kw_onlyvalue}")31 print(f"**kwargs: {kwargs{'opt1': 'a', 'opt2': 'b'}}")outputrequired: required *args: ('extra1', 'extra2') kw_only: value **kwargs: {'opt1': 'a', 'opt2': 'b'} === Catch-All Function ===def catch_all(*args, **kwargs): #?catchall_fn
13 print("\n=== Catch-All Function ===") #?catchall14 catch_all(1, 2, 3, name="test", flag=True)1516def log(level, message, *tags, **metadata): #?signature17 """Log with optional tags and metadata."""18 print(f"[{level}] {message}")19 if tags:20 print(f" Tags: {', '.join(tags)}")21 if metadata:22 for key, value in metadata.items():23 print(f" {key}: {value}")24 print()2526def demonstrate_order(required, *args, kw_only, **kwargs): #?fullorder27 """Show the required parameter order."""28 print(f"required: {required}")29 print(f"*args: {args}")30 print(f"kw_only: {kw_only}")31 print(f"**kwargs: {kwargs}")3233def catch_all(*args(1, 2, 3), **kwargs): #?catchall_fn34 """Accept literally anything."""35 print(f"Positional ({len(args(1, 2, 3))}): {args}")36 print(f"Keyword ({len(kwargs{'name': 'test', 'flag': True})}): {kwargs}")outputPositional (3): (1, 2, 3) Keyword (2): {'name': 'test', 'flag': True}main()
38if __name__ == "__main__":39 main()40#@help combined
Order matters: regular params, *args, keyword-only params, **kwargs.
Unpack into function calls
Use * and ** to expand sequences and dicts into arguments.
def main():
print("=== Unpacking: * and ** in Function Calls ===\n")
# Unpack list/tuple into positional args
numbers = [10, 20, 30]
print(f"numbers = {numbers}")
print(f"add(numbers) would fail - it's one arg")
print(f"add(*numbers) = {add(*numbers)}") # Unpacks!
print("\n=== Unpack Dict into Keyword Args ===")
config = {'host': 'localhost', 'port': 8080, 'debug': True}
print(f"config = {config}")
connect(**config) # Same as connect(host='...', port=..., debug=...)
print("\n=== Combined Unpacking ===")
args = [5, 3]
kwargs = {'operation': 'multiply'}
calculate(*args, **kwargs)
print("\n=== Range Example ===")
# start, stop, step
bounds = (1, 10, 2)
print(f"bounds = {bounds}")
print(f"list(range(*bounds)) = {list(range(*bounds))}")
print("\n=== Merge Dicts with ** ===")
defaults = {'color': 'blue', 'size': 'medium'}
overrides = {'size': 'large', 'style': 'bold'}
merged = {**defaults, **overrides}
print(f"defaults: {defaults}")
print(f"overrides: {overrides}")
print(f"merged: {merged}")
def add(a, b, c):
"""Add three numbers."""
return a + b + c
def connect(host, port, debug=False):
"""Simulate connection."""
print(f"Connecting to {host}:{port} (debug={debug})")
def calculate(x, y, operation='add'):
"""Perform calculation."""
if operation == 'add':
print(f"{x} + {y} = {x + y}")
elif operation == 'multiply':
print(f"{x} * {y} = {x * y}")
if __name__ == "__main__":
main()
def main():
print("=== Unpacking: * and ** in Function Calls ===\n")
# Unpack list/tuple into positional args
numbers = [1, 2, 3]
print(f"numbers = {numbers}")
print(f"add(numbers) would fail - it's one arg")
print(f"add(*numbers) = {add(*numbers)}") # Unpacks!
print("\n=== Unpack Dict into Keyword Args ===")
config = {'host': 'localhost', 'port': 8080, 'debug': True}
print(f"config = {config}")
connect(**config) # Same as connect(host='...', port=..., debug=...)
print("\n=== Combined Unpacking ===")
args = [5, 3]
kwargs = {'operation': 'multiply'}
calculate(*args, **kwargs)
print("\n=== Range Example ===")
# start, stop, step
bounds = (1, 10, 2)
print(f"bounds = {bounds}")
print(f"list(range(*bounds)) = {list(range(*bounds))}")
print("\n=== Merge Dicts with ** ===")
defaults = {'color': 'blue', 'size': 'medium'}
overrides = {'size': 'large', 'style': 'bold'}
merged = {**defaults, **overrides}
print(f"defaults: {defaults}")
print(f"overrides: {overrides}")
print(f"merged: {merged}")
def add(a, b, c):
"""Add three numbers."""
return a + b + c
def connect(host, port, debug=False):
"""Simulate connection."""
print(f"Connecting to {host}:{port} (debug={debug})")
def calculate(x, y, operation='add'):
"""Perform calculation."""
if operation == 'add':
print(f"{x} + {y} = {x + y}")
elif operation == 'multiply':
print(f"{x} * {y} = {x * y}")
if __name__ == "__main__":
main()
def main():
print("=== Unpacking: * and ** in Function Calls ===\n")
# Unpack list/tuple into positional args
numbers = [5, 10, 15]
print(f"numbers = {numbers}")
print(f"add(numbers) would fail - it's one arg")
print(f"add(*numbers) = {add(*numbers)}") # Unpacks!
print("\n=== Unpack Dict into Keyword Args ===")
config = {'host': 'localhost', 'port': 8080, 'debug': True}
print(f"config = {config}")
connect(**config) # Same as connect(host='...', port=..., debug=...)
print("\n=== Combined Unpacking ===")
args = [5, 3]
kwargs = {'operation': 'multiply'}
calculate(*args, **kwargs)
print("\n=== Range Example ===")
# start, stop, step
bounds = (1, 10, 2)
print(f"bounds = {bounds}")
print(f"list(range(*bounds)) = {list(range(*bounds))}")
print("\n=== Merge Dicts with ** ===")
defaults = {'color': 'blue', 'size': 'medium'}
overrides = {'size': 'large', 'style': 'bold'}
merged = {**defaults, **overrides}
print(f"defaults: {defaults}")
print(f"overrides: {overrides}")
print(f"merged: {merged}")
def add(a, b, c):
"""Add three numbers."""
return a + b + c
def connect(host, port, debug=False):
"""Simulate connection."""
print(f"Connecting to {host}:{port} (debug={debug})")
def calculate(x, y, operation='add'):
"""Perform calculation."""
if operation == 'add':
print(f"{x} + {y} = {x + y}")
elif operation == 'multiply':
print(f"{x} * {y} = {x * y}")
if __name__ == "__main__":
main()
def main():
print("=== Unpacking: * and ** in Function Calls ===\n")
# Unpack list/tuple into positional args
numbers = [10, 20, 30]
print(f"numbers = {numbers}")
print(f"add(numbers) would fail - it's one arg")
print(f"add(*numbers) = {add(*numbers)}") # Unpacks!
print("\n=== Unpack Dict into Keyword Args ===")
config = {'host': 'localhost', 'port': 8080, 'debug': True}
print(f"config = {config}")
connect(**config) # Same as connect(host='...', port=..., debug=...)
print("\n=== Combined Unpacking ===")
args = [5, 3]
kwargs = {'operation': 'multiply'}
calculate(*args, **kwargs)
print("\n=== Range Example ===")
# start, stop, step
bounds = (0, 12, 3)
print(f"bounds = {bounds}")
print(f"list(range(*bounds)) = {list(range(*bounds))}")
print("\n=== Merge Dicts with ** ===")
defaults = {'color': 'blue', 'size': 'medium'}
overrides = {'size': 'large', 'style': 'bold'}
merged = {**defaults, **overrides}
print(f"defaults: {defaults}")
print(f"overrides: {overrides}")
print(f"merged: {merged}")
def add(a, b, c):
"""Add three numbers."""
return a + b + c
def connect(host, port, debug=False):
"""Simulate connection."""
print(f"Connecting to {host}:{port} (debug={debug})")
def calculate(x, y, operation='add'):
"""Perform calculation."""
if operation == 'add':
print(f"{x} + {y} = {x + y}")
elif operation == 'multiply':
print(f"{x} * {y} = {x * y}")
if __name__ == "__main__":
main()
def main():
print("=== Unpacking: * and ** in Function Calls ===\n")
# Unpack list/tuple into positional args
numbers = [10, 20, 30]
print(f"numbers = {numbers}")
print(f"add(numbers) would fail - it's one arg")
print(f"add(*numbers) = {add(*numbers)}") # Unpacks!
print("\n=== Unpack Dict into Keyword Args ===")
config = {'host': 'localhost', 'port': 8080, 'debug': True}
print(f"config = {config}")
connect(**config) # Same as connect(host='...', port=..., debug=...)
print("\n=== Combined Unpacking ===")
args = [5, 3]
kwargs = {'operation': 'multiply'}
calculate(*args, **kwargs)
print("\n=== Range Example ===")
# start, stop, step
bounds = (2, 9, 2)
print(f"bounds = {bounds}")
print(f"list(range(*bounds)) = {list(range(*bounds))}")
print("\n=== Merge Dicts with ** ===")
defaults = {'color': 'blue', 'size': 'medium'}
overrides = {'size': 'large', 'style': 'bold'}
merged = {**defaults, **overrides}
print(f"defaults: {defaults}")
print(f"overrides: {overrides}")
print(f"merged: {merged}")
def add(a, b, c):
"""Add three numbers."""
return a + b + c
def connect(host, port, debug=False):
"""Simulate connection."""
print(f"Connecting to {host}:{port} (debug={debug})")
def calculate(x, y, operation='add'):
"""Perform calculation."""
if operation == 'add':
print(f"{x} + {y} = {x + y}")
elif operation == 'multiply':
print(f"{x} * {y} = {x * y}")
if __name__ == "__main__":
main()
numbers ← [10, 20, 30]
1#@var=default,advanced2def main():3 print("=== Unpacking: * and ** in Function Calls ===\n")4 5 # Unpack list/tuple into positional args #?unpack_list6 numbers→ [10, 20, 30] = [10, 20, 30] #@numbers=[1, 2, 3], [5, 10, 15]7 print(f"numbers = {numbers[10, 20, 30]}")8 print(f"add(numbers) would fail - it's one arg")9 print(f"add(*numbers) = {add(*numbers[10, 20, 30])}") # Unpacks!output=== Unpacking: * and ** in Function Calls === numbers = [10, 20, 30] add(numbers) would fail - it's one argdef add(a, b, c):
37def add(a10, b20, c30):38 """Add three numbers."""39 return a10 + b20 + c30config ← {'host': 'localhost', 'port': 8080, 'debug': True}
8print(f"add(numbers) would fail - it's one arg")9print(f"add(*numbers) = {add(*numbers[10, 20, 30])}") # Unpacks!1011print("\n=== Unpack Dict into Keyword Args ===") #?unpack_dict12config→ {'host': 'localhost', 'port': 8080, 'debug': True} = {'host': 'localhost', 'port': 8080, 'debug': True}13print(f"config = {config{'host': 'localhost', 'port': 8080, 'debug': True}}")14connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)outputadd(*numbers) = 60 === Unpack Dict into Keyword Args === config = {'host': 'localhost', 'port': 8080, 'debug': True}args ← [5, 3], kwargs ← {'operation': 'multiply'}
13 print(f"config = {config}")14 connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)15 16 print("\n=== Combined Unpacking ===") #?combined17 args→ [5, 3] = [5, 3]18 kwargs→ {'operation': 'multiply'} = {'operation': 'multiply'}19 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})20 21 print("\n=== Range Example ===") #?range22 # start, stop, step23 bounds = (1, 10, 2) #@bounds=(0, 12, 3), (2, 9, 2)24 print(f"bounds = {bounds}")25 print(f"list(range(*bounds)) = {list(range(*bounds))}")26 27 #@var=_,!28 print("\n=== Merge Dicts with ** ===")29 defaults = {'color': 'blue', 'size': 'medium'}30 overrides = {'size': 'large', 'style': 'bold'}31 merged = {**defaults, **overrides} #?merge32 print(f"defaults: {defaults}")33 print(f"overrides: {overrides}")34 print(f"merged: {merged}")35 #@var=_,!3637def add(a, b, c):38 """Add three numbers."""39 return a + b + c4041def connect(hostlocalhost, port8080, debugTrue=FalseFalse): #?connect42 """Simulate connection."""43 print(f"Connecting to {hostlocalhost}:{port8080} (debug={debugTrue})")outputConnecting to localhost:8080 (debug=True) === Combined Unpacking ===def calculate(x, y, operation='add'):
45def calculate(x5, y3, operationmultiply='add'):46 """Perform calculation."""47 if operation == 'add':bounds ← (1, 10, 2), defaults ← {'color': 'blue', 'size': 'medium'}
18 kwargs = {'operation': 'multiply'}19 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})20 21 print("\n=== Range Example ===") #?range22 # start, stop, step23 bounds→ (1, 10, 2) = (1, 10, 2) #@bounds=(0, 12, 3), (2, 9, 2)24 print(f"bounds = {bounds(1, 10, 2)}")25 print(f"list(range(*bounds)) = {list(range(*bounds(1, 10, 2)))}")26 27 #@var=_,!28 print("\n=== Merge Dicts with ** ===")29 defaults→ {'color': 'blue', 'size': 'medium'} = {'color': 'blue', 'size': 'medium'}30 overrides→ {'size': 'large', 'style': 'bold'} = {'size': 'large', 'style': 'bold'}31 merged→ {'color': 'blue', 'size': 'large', 'style': 'bold'} = {**defaults{'color': 'blue', 'size': 'medium'}, **overrides{'size': 'large', 'style': 'bold'}} #?merge32 print(f"defaults: {defaults{'color': 'blue', 'size': 'medium'}}")33 print(f"overrides: {overrides{'size': 'large', 'style': 'bold'}}")34 print(f"merged: {merged{'color': 'blue', 'size': 'large', 'style': 'bold'}}")35 #@var=_,!3637def add(a, b, c):38 """Add three numbers."""39 return a + b + c4041def connect(host, port, debug=False): #?connect42 """Simulate connection."""43 print(f"Connecting to {host}:{port} (debug={debug})")4445def calculate(x, y, operation='add'):46 """Perform calculation."""47 if operation == 'add':48 print(f"{x} + {y} = {x + y}")49 elif operationmultiply == 'multiply':50 print(f"{x5} * {y3} = {x * y}")output5 * 3 = 15 === Range Example === bounds = (1, 10, 2) list(range(*bounds)) = [1, 3, 5, 7, 9] === Merge Dicts with ** === defaults: {'color': 'blue', 'size': 'medium'} overrides: {'size': 'large', 'style': 'bold'} merged: {'color': 'blue', 'size': 'large', 'style': 'bold'}main()
52if __name__ == "__main__":53 main()54#@help unpack_list
numbers ← [1, 2, 3]
1def main():2 print("=== Unpacking: * and ** in Function Calls ===\n")3 4 # Unpack list/tuple into positional args5 numbers→ [1, 2, 3] = [1, 2, 3]6 print(f"numbers = {numbers[1, 2, 3]}")7 print(f"add(numbers) would fail - it's one arg")8 print(f"add(*numbers) = {add(*numbers[1, 2, 3])}") # Unpacks!output=== Unpacking: * and ** in Function Calls === numbers = [1, 2, 3] add(numbers) would fail - it's one argdef add(a, b, c):
34def add(a1, b2, c3):35 """Add three numbers."""36 return a1 + b2 + c3config ← {'host': 'localhost', 'port': 8080, 'debug': True}
7print(f"add(numbers) would fail - it's one arg")8print(f"add(*numbers) = {add(*numbers[1, 2, 3])}") # Unpacks!910print("\n=== Unpack Dict into Keyword Args ===")11config→ {'host': 'localhost', 'port': 8080, 'debug': True} = {'host': 'localhost', 'port': 8080, 'debug': True}12print(f"config = {config{'host': 'localhost', 'port': 8080, 'debug': True}}")13connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)outputadd(*numbers) = 6 === Unpack Dict into Keyword Args === config = {'host': 'localhost', 'port': 8080, 'debug': True}args ← [5, 3], kwargs ← {'operation': 'multiply'}
12 print(f"config = {config}")13 connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)14 15 print("\n=== Combined Unpacking ===")16 args→ [5, 3] = [5, 3]17 kwargs→ {'operation': 'multiply'} = {'operation': 'multiply'}18 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})19 20 print("\n=== Range Example ===")21 # start, stop, step22 bounds = (1, 10, 2)23 print(f"bounds = {bounds}")24 print(f"list(range(*bounds)) = {list(range(*bounds))}")25 26 print("\n=== Merge Dicts with ** ===")27 defaults = {'color': 'blue', 'size': 'medium'}28 overrides = {'size': 'large', 'style': 'bold'}29 merged = {**defaults, **overrides}30 print(f"defaults: {defaults}")31 print(f"overrides: {overrides}")32 print(f"merged: {merged}")3334def add(a, b, c):35 """Add three numbers."""36 return a + b + c3738def connect(hostlocalhost, port8080, debugTrue=FalseFalse):39 """Simulate connection."""40 print(f"Connecting to {hostlocalhost}:{port8080} (debug={debugTrue})")outputConnecting to localhost:8080 (debug=True) === Combined Unpacking ===def calculate(x, y, operation='add'):
42def calculate(x5, y3, operationmultiply='add'):43 """Perform calculation."""44 if operation == 'add':bounds ← (1, 10, 2), defaults ← {'color': 'blue', 'size': 'medium'}
17 kwargs = {'operation': 'multiply'}18 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})19 20 print("\n=== Range Example ===")21 # start, stop, step22 bounds→ (1, 10, 2) = (1, 10, 2)23 print(f"bounds = {bounds(1, 10, 2)}")24 print(f"list(range(*bounds)) = {list(range(*bounds(1, 10, 2)))}")25 26 print("\n=== Merge Dicts with ** ===")27 defaults→ {'color': 'blue', 'size': 'medium'} = {'color': 'blue', 'size': 'medium'}28 overrides→ {'size': 'large', 'style': 'bold'} = {'size': 'large', 'style': 'bold'}29 merged→ {'color': 'blue', 'size': 'large', 'style': 'bold'} = {**defaults{'color': 'blue', 'size': 'medium'}, **overrides{'size': 'large', 'style': 'bold'}}30 print(f"defaults: {defaults{'color': 'blue', 'size': 'medium'}}")31 print(f"overrides: {overrides{'size': 'large', 'style': 'bold'}}")32 print(f"merged: {merged{'color': 'blue', 'size': 'large', 'style': 'bold'}}")3334def add(a, b, c):35 """Add three numbers."""36 return a + b + c3738def connect(host, port, debug=False):39 """Simulate connection."""40 print(f"Connecting to {host}:{port} (debug={debug})")4142def calculate(x, y, operation='add'):43 """Perform calculation."""44 if operation == 'add':45 print(f"{x} + {y} = {x + y}")46 elif operationmultiply == 'multiply':47 print(f"{x5} * {y3} = {x * y}")output5 * 3 = 15 === Range Example === bounds = (1, 10, 2) list(range(*bounds)) = [1, 3, 5, 7, 9] === Merge Dicts with ** === defaults: {'color': 'blue', 'size': 'medium'} overrides: {'size': 'large', 'style': 'bold'} merged: {'color': 'blue', 'size': 'large', 'style': 'bold'}main()
49if __name__ == "__main__":50 main()
numbers ← [5, 10, 15]
1def main():2 print("=== Unpacking: * and ** in Function Calls ===\n")3 4 # Unpack list/tuple into positional args5 numbers→ [5, 10, 15] = [5, 10, 15]6 print(f"numbers = {numbers[5, 10, 15]}")7 print(f"add(numbers) would fail - it's one arg")8 print(f"add(*numbers) = {add(*numbers[5, 10, 15])}") # Unpacks!output=== Unpacking: * and ** in Function Calls === numbers = [5, 10, 15] add(numbers) would fail - it's one argdef add(a, b, c):
34def add(a5, b10, c15):35 """Add three numbers."""36 return a5 + b10 + c15config ← {'host': 'localhost', 'port': 8080, 'debug': True}
7print(f"add(numbers) would fail - it's one arg")8print(f"add(*numbers) = {add(*numbers[5, 10, 15])}") # Unpacks!910print("\n=== Unpack Dict into Keyword Args ===")11config→ {'host': 'localhost', 'port': 8080, 'debug': True} = {'host': 'localhost', 'port': 8080, 'debug': True}12print(f"config = {config{'host': 'localhost', 'port': 8080, 'debug': True}}")13connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)outputadd(*numbers) = 30 === Unpack Dict into Keyword Args === config = {'host': 'localhost', 'port': 8080, 'debug': True}args ← [5, 3], kwargs ← {'operation': 'multiply'}
12 print(f"config = {config}")13 connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)14 15 print("\n=== Combined Unpacking ===")16 args→ [5, 3] = [5, 3]17 kwargs→ {'operation': 'multiply'} = {'operation': 'multiply'}18 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})19 20 print("\n=== Range Example ===")21 # start, stop, step22 bounds = (1, 10, 2)23 print(f"bounds = {bounds}")24 print(f"list(range(*bounds)) = {list(range(*bounds))}")25 26 print("\n=== Merge Dicts with ** ===")27 defaults = {'color': 'blue', 'size': 'medium'}28 overrides = {'size': 'large', 'style': 'bold'}29 merged = {**defaults, **overrides}30 print(f"defaults: {defaults}")31 print(f"overrides: {overrides}")32 print(f"merged: {merged}")3334def add(a, b, c):35 """Add three numbers."""36 return a + b + c3738def connect(hostlocalhost, port8080, debugTrue=FalseFalse):39 """Simulate connection."""40 print(f"Connecting to {hostlocalhost}:{port8080} (debug={debugTrue})")outputConnecting to localhost:8080 (debug=True) === Combined Unpacking ===def calculate(x, y, operation='add'):
42def calculate(x5, y3, operationmultiply='add'):43 """Perform calculation."""44 if operation == 'add':bounds ← (1, 10, 2), defaults ← {'color': 'blue', 'size': 'medium'}
17 kwargs = {'operation': 'multiply'}18 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})19 20 print("\n=== Range Example ===")21 # start, stop, step22 bounds→ (1, 10, 2) = (1, 10, 2)23 print(f"bounds = {bounds(1, 10, 2)}")24 print(f"list(range(*bounds)) = {list(range(*bounds(1, 10, 2)))}")25 26 print("\n=== Merge Dicts with ** ===")27 defaults→ {'color': 'blue', 'size': 'medium'} = {'color': 'blue', 'size': 'medium'}28 overrides→ {'size': 'large', 'style': 'bold'} = {'size': 'large', 'style': 'bold'}29 merged→ {'color': 'blue', 'size': 'large', 'style': 'bold'} = {**defaults{'color': 'blue', 'size': 'medium'}, **overrides{'size': 'large', 'style': 'bold'}}30 print(f"defaults: {defaults{'color': 'blue', 'size': 'medium'}}")31 print(f"overrides: {overrides{'size': 'large', 'style': 'bold'}}")32 print(f"merged: {merged{'color': 'blue', 'size': 'large', 'style': 'bold'}}")3334def add(a, b, c):35 """Add three numbers."""36 return a + b + c3738def connect(host, port, debug=False):39 """Simulate connection."""40 print(f"Connecting to {host}:{port} (debug={debug})")4142def calculate(x, y, operation='add'):43 """Perform calculation."""44 if operation == 'add':45 print(f"{x} + {y} = {x + y}")46 elif operationmultiply == 'multiply':47 print(f"{x5} * {y3} = {x * y}")output5 * 3 = 15 === Range Example === bounds = (1, 10, 2) list(range(*bounds)) = [1, 3, 5, 7, 9] === Merge Dicts with ** === defaults: {'color': 'blue', 'size': 'medium'} overrides: {'size': 'large', 'style': 'bold'} merged: {'color': 'blue', 'size': 'large', 'style': 'bold'}main()
49if __name__ == "__main__":50 main()
numbers ← [10, 20, 30]
1def main():2 print("=== Unpacking: * and ** in Function Calls ===\n")3 4 # Unpack list/tuple into positional args5 numbers→ [10, 20, 30] = [10, 20, 30]6 print(f"numbers = {numbers[10, 20, 30]}")7 print(f"add(numbers) would fail - it's one arg")8 print(f"add(*numbers) = {add(*numbers[10, 20, 30])}") # Unpacks!output=== Unpacking: * and ** in Function Calls === numbers = [10, 20, 30] add(numbers) would fail - it's one argdef add(a, b, c):
34def add(a10, b20, c30):35 """Add three numbers."""36 return a10 + b20 + c30config ← {'host': 'localhost', 'port': 8080, 'debug': True}
7print(f"add(numbers) would fail - it's one arg")8print(f"add(*numbers) = {add(*numbers[10, 20, 30])}") # Unpacks!910print("\n=== Unpack Dict into Keyword Args ===")11config→ {'host': 'localhost', 'port': 8080, 'debug': True} = {'host': 'localhost', 'port': 8080, 'debug': True}12print(f"config = {config{'host': 'localhost', 'port': 8080, 'debug': True}}")13connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)outputadd(*numbers) = 60 === Unpack Dict into Keyword Args === config = {'host': 'localhost', 'port': 8080, 'debug': True}args ← [5, 3], kwargs ← {'operation': 'multiply'}
12 print(f"config = {config}")13 connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)14 15 print("\n=== Combined Unpacking ===")16 args→ [5, 3] = [5, 3]17 kwargs→ {'operation': 'multiply'} = {'operation': 'multiply'}18 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})19 20 print("\n=== Range Example ===")21 # start, stop, step22 bounds = (0, 12, 3)23 print(f"bounds = {bounds}")24 print(f"list(range(*bounds)) = {list(range(*bounds))}")25 26 print("\n=== Merge Dicts with ** ===")27 defaults = {'color': 'blue', 'size': 'medium'}28 overrides = {'size': 'large', 'style': 'bold'}29 merged = {**defaults, **overrides}30 print(f"defaults: {defaults}")31 print(f"overrides: {overrides}")32 print(f"merged: {merged}")3334def add(a, b, c):35 """Add three numbers."""36 return a + b + c3738def connect(hostlocalhost, port8080, debugTrue=FalseFalse):39 """Simulate connection."""40 print(f"Connecting to {hostlocalhost}:{port8080} (debug={debugTrue})")outputConnecting to localhost:8080 (debug=True) === Combined Unpacking ===def calculate(x, y, operation='add'):
42def calculate(x5, y3, operationmultiply='add'):43 """Perform calculation."""44 if operation == 'add':bounds ← (0, 12, 3), defaults ← {'color': 'blue', 'size': 'medium'}
17 kwargs = {'operation': 'multiply'}18 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})19 20 print("\n=== Range Example ===")21 # start, stop, step22 bounds→ (0, 12, 3) = (0, 12, 3)23 print(f"bounds = {bounds(0, 12, 3)}")24 print(f"list(range(*bounds)) = {list(range(*bounds(0, 12, 3)))}")25 26 print("\n=== Merge Dicts with ** ===")27 defaults→ {'color': 'blue', 'size': 'medium'} = {'color': 'blue', 'size': 'medium'}28 overrides→ {'size': 'large', 'style': 'bold'} = {'size': 'large', 'style': 'bold'}29 merged→ {'color': 'blue', 'size': 'large', 'style': 'bold'} = {**defaults{'color': 'blue', 'size': 'medium'}, **overrides{'size': 'large', 'style': 'bold'}}30 print(f"defaults: {defaults{'color': 'blue', 'size': 'medium'}}")31 print(f"overrides: {overrides{'size': 'large', 'style': 'bold'}}")32 print(f"merged: {merged{'color': 'blue', 'size': 'large', 'style': 'bold'}}")3334def add(a, b, c):35 """Add three numbers."""36 return a + b + c3738def connect(host, port, debug=False):39 """Simulate connection."""40 print(f"Connecting to {host}:{port} (debug={debug})")4142def calculate(x, y, operation='add'):43 """Perform calculation."""44 if operation == 'add':45 print(f"{x} + {y} = {x + y}")46 elif operationmultiply == 'multiply':47 print(f"{x5} * {y3} = {x * y}")output5 * 3 = 15 === Range Example === bounds = (0, 12, 3) list(range(*bounds)) = [0, 3, 6, 9] === Merge Dicts with ** === defaults: {'color': 'blue', 'size': 'medium'} overrides: {'size': 'large', 'style': 'bold'} merged: {'color': 'blue', 'size': 'large', 'style': 'bold'}main()
49if __name__ == "__main__":50 main()
numbers ← [10, 20, 30]
1def main():2 print("=== Unpacking: * and ** in Function Calls ===\n")3 4 # Unpack list/tuple into positional args5 numbers→ [10, 20, 30] = [10, 20, 30]6 print(f"numbers = {numbers[10, 20, 30]}")7 print(f"add(numbers) would fail - it's one arg")8 print(f"add(*numbers) = {add(*numbers[10, 20, 30])}") # Unpacks!output=== Unpacking: * and ** in Function Calls === numbers = [10, 20, 30] add(numbers) would fail - it's one argdef add(a, b, c):
34def add(a10, b20, c30):35 """Add three numbers."""36 return a10 + b20 + c30config ← {'host': 'localhost', 'port': 8080, 'debug': True}
7print(f"add(numbers) would fail - it's one arg")8print(f"add(*numbers) = {add(*numbers[10, 20, 30])}") # Unpacks!910print("\n=== Unpack Dict into Keyword Args ===")11config→ {'host': 'localhost', 'port': 8080, 'debug': True} = {'host': 'localhost', 'port': 8080, 'debug': True}12print(f"config = {config{'host': 'localhost', 'port': 8080, 'debug': True}}")13connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)outputadd(*numbers) = 60 === Unpack Dict into Keyword Args === config = {'host': 'localhost', 'port': 8080, 'debug': True}args ← [5, 3], kwargs ← {'operation': 'multiply'}
12 print(f"config = {config}")13 connect(**config{'host': 'localhost', 'port': 8080, 'debug': True}) # Same as connect(host='...', port=..., debug=...)14 15 print("\n=== Combined Unpacking ===")16 args→ [5, 3] = [5, 3]17 kwargs→ {'operation': 'multiply'} = {'operation': 'multiply'}18 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})19 20 print("\n=== Range Example ===")21 # start, stop, step22 bounds = (2, 9, 2)23 print(f"bounds = {bounds}")24 print(f"list(range(*bounds)) = {list(range(*bounds))}")25 26 print("\n=== Merge Dicts with ** ===")27 defaults = {'color': 'blue', 'size': 'medium'}28 overrides = {'size': 'large', 'style': 'bold'}29 merged = {**defaults, **overrides}30 print(f"defaults: {defaults}")31 print(f"overrides: {overrides}")32 print(f"merged: {merged}")3334def add(a, b, c):35 """Add three numbers."""36 return a + b + c3738def connect(hostlocalhost, port8080, debugTrue=FalseFalse):39 """Simulate connection."""40 print(f"Connecting to {hostlocalhost}:{port8080} (debug={debugTrue})")outputConnecting to localhost:8080 (debug=True) === Combined Unpacking ===def calculate(x, y, operation='add'):
42def calculate(x5, y3, operationmultiply='add'):43 """Perform calculation."""44 if operation == 'add':bounds ← (2, 9, 2), defaults ← {'color': 'blue', 'size': 'medium'}
17 kwargs = {'operation': 'multiply'}18 calculate(*args[5, 3], **kwargs{'operation': 'multiply'})19 20 print("\n=== Range Example ===")21 # start, stop, step22 bounds→ (2, 9, 2) = (2, 9, 2)23 print(f"bounds = {bounds(2, 9, 2)}")24 print(f"list(range(*bounds)) = {list(range(*bounds(2, 9, 2)))}")25 26 print("\n=== Merge Dicts with ** ===")27 defaults→ {'color': 'blue', 'size': 'medium'} = {'color': 'blue', 'size': 'medium'}28 overrides→ {'size': 'large', 'style': 'bold'} = {'size': 'large', 'style': 'bold'}29 merged→ {'color': 'blue', 'size': 'large', 'style': 'bold'} = {**defaults{'color': 'blue', 'size': 'medium'}, **overrides{'size': 'large', 'style': 'bold'}}30 print(f"defaults: {defaults{'color': 'blue', 'size': 'medium'}}")31 print(f"overrides: {overrides{'size': 'large', 'style': 'bold'}}")32 print(f"merged: {merged{'color': 'blue', 'size': 'large', 'style': 'bold'}}")3334def add(a, b, c):35 """Add three numbers."""36 return a + b + c3738def connect(host, port, debug=False):39 """Simulate connection."""40 print(f"Connecting to {host}:{port} (debug={debug})")4142def calculate(x, y, operation='add'):43 """Perform calculation."""44 if operation == 'add':45 print(f"{x} + {y} = {x + y}")46 elif operationmultiply == 'multiply':47 print(f"{x5} * {y3} = {x * y}")output5 * 3 = 15 === Range Example === bounds = (2, 9, 2) list(range(*bounds)) = [2, 4, 6, 8] === Merge Dicts with ** === defaults: {'color': 'blue', 'size': 'medium'} overrides: {'size': 'large', 'style': 'bold'} merged: {'color': 'blue', 'size': 'large', 'style': 'bold'}main()
49if __name__ == "__main__":50 main()
func(*list) unpacks list as positional args. func(**dict) unpacks as keyword args.
Forward arguments to other functions
Pass received arguments to another function unchanged.
def main():
print("=== Forwarding Arguments ===\n")
# Wrapper forwards to inner function
print("Wrapper forwarding:")
wrapper_example(1, 2, 3, name="test", flag=True)
print("\n=== Logging Wrapper ===")
logged_add(10, 20)
logged_multiply(5, 3, verbose=True)
print("\n=== Super() Forwarding ===")
fancy = FancyButton("Click Me", color="blue", size="large")
def wrapper_example(*args, **kwargs):
"""Wrapper that forwards everything."""
print(f" Wrapper received: args={args}, kwargs={kwargs}")
print(" Forwarding to inner function...")
inner_function(*args, **kwargs)
def inner_function(*args, **kwargs):
print(f" Inner got: args={args}, kwargs={kwargs}")
# Logging wrapper pattern
def logged_add(a, b):
print(f" [LOG] Calling add({a}, {b})")
result = a + b
print(f" [LOG] Result: {result}")
return result
def logged_multiply(a, b, verbose=False):
if verbose:
print(f" [VERBOSE] multiply called with a={a}, b={b}")
result = a * b
print(f" [LOG] multiply result: {result}")
return result
# Class inheritance forwarding
class Button:
def __init__(self, text, **options):
self.text = text
self.options = options
print(f" Button created: '{text}' with {options}")
class FancyButton(Button):
def __init__(self, text, **options):
# Add default options
options.setdefault('border', True)
# Forward to parent
super().__init__(text, **options)
print(" (FancyButton enhancements applied)")
if __name__ == "__main__":
main()
def main():
1def main():2 print("=== Forwarding Arguments ===\n")3 4 # Wrapper forwards to inner function #?forward5 print("Wrapper forwarding:")6 wrapper_example(1, 2, 3, name="test", flag=True)output=== Forwarding Arguments === Wrapper forwarding:def wrapper_example(*args, **kwargs): #?wrapper
15def wrapper_example(*args(1, 2, 3), **kwargs): #?wrapper16 """Wrapper that forwards everything."""17 print(f" Wrapper received: args={args(1, 2, 3)}, kwargs={kwargs{'name': 'test', 'flag': True}}")18 print(" Forwarding to inner function...")19 inner_function(*args(1, 2, 3), **kwargs{'name': 'test', 'flag': True})output Wrapper received: args=(1, 2, 3), kwargs={'name': 'test', 'flag': True} Forwarding to inner function...def inner_function(*args, **kwargs):
5 print("Wrapper forwarding:")6 wrapper_example(1, 2, 3, name="test", flag=True)7 8 print("\n=== Logging Wrapper ===") #?logging9 logged_add(10, 20)10 logged_multiply(5, 3, verbose=True)11 12 print("\n=== Super() Forwarding ===") #?super13 fancy = FancyButton("Click Me", color="blue", size="large")1415def wrapper_example(*args, **kwargs): #?wrapper16 """Wrapper that forwards everything."""17 print(f" Wrapper received: args={args}, kwargs={kwargs}")18 print(" Forwarding to inner function...")19 inner_function(*args(1, 2, 3), **kwargs{'name': 'test', 'flag': True})2021def inner_function(*args(1, 2, 3), **kwargs):22 print(f" Inner got: args={args(1, 2, 3)}, kwargs={kwargs{'name': 'test', 'flag': True}}")output Inner got: args=(1, 2, 3), kwargs={'name': 'test', 'flag': True} === Logging Wrapper ===result ← 30
24# Logging wrapper pattern #?logwrapper25def logged_add(a10, b20):26 print(f" [LOG] Calling add({a10}, {b20})")27 result→ 30 = a10 + b2028 print(f" [LOG] Result: {result30}")29 return result30output [LOG] Calling add(10, 20) [LOG] Result: 30logged_add(10, 20)
8print("\n=== Logging Wrapper ===") #?logging9logged_add(10, 20)10logged_multiply(5, 3, verbose=True)def logged_multiply(a, b, verbose=False):
31def logged_multiply(a5, b3, verboseTrue=FalseFalse):32 if verbose:33 print(f" [VERBOSE] multiply called with a={a}, b={b}")if verbose:
31def logged_multiply(a, b, verbose=False):32 if verboseTrue:33 print(f" [VERBOSE] multiply called with a={a5}, b={b3}")34 result = a * boutput [VERBOSE] multiply called with a=5, b=3result ← 15
33 print(f" [VERBOSE] multiply called with a={a}, b={b}")34result→ 15 = a5 * b335print(f" [LOG] multiply result: {result15}")36return result15output [LOG] multiply result: 15logged_multiply(5, 3, verbose=True)
9logged_add(10, 20)10logged_multiply(5, 3, verbose=True)1112print("\n=== Super() Forwarding ===") #?super13fancy = FancyButton("Click Me", color="blue", size="large")output === Super() Forwarding ===options ← {'color': 'blue', 'size': 'large', 'border': True}
45class FancyButton(Button):46 def __init__(self⟨FancyButton A⟩, textClick Me, **options): #?derivedinit47 # Add default options48 options→ {'color': 'blue', 'size': 'large', 'border': True}.setdefault('border', True)49 # Forward to parentself.text ← Click Me, self.options ← {'color': 'blue', 'size': 'large', 'border': True}
39class Button:40 def __init__(self⟨FancyButton A⟩, textClick Me, **options): #?baseinit41 self.text→ Click Me = textClick Me42 self.options→ {'color': 'blue', 'size': 'large', 'border': True} = options{'color': 'blue', 'size': 'large', 'border': True}43 print(f" Button created: '{textClick Me}' with {options{'color': 'blue', 'size': 'large', 'border': True}}")output Button created: 'Click Me' with {'color': 'blue', 'size': 'large', 'border': True}fancy ← ⟨FancyButton A⟩
12 print("\n=== Super() Forwarding ===") #?super13 fancy→ ⟨FancyButton A⟩ = FancyButton("Click Me", color="blue", size="large")1415def wrapper_example(*args, **kwargs): #?wrapper16 """Wrapper that forwards everything."""17 print(f" Wrapper received: args={args}, kwargs={kwargs}")18 print(" Forwarding to inner function...")19 inner_function(*args, **kwargs)2021def inner_function(*args, **kwargs):22 print(f" Inner got: args={args}, kwargs={kwargs}")2324# Logging wrapper pattern #?logwrapper25def logged_add(a, b):26 print(f" [LOG] Calling add({a}, {b})")27 result = a + b28 print(f" [LOG] Result: {result}")29 return result3031def logged_multiply(a, b, verbose=False):32 if verbose:33 print(f" [VERBOSE] multiply called with a={a}, b={b}")34 result = a * b35 print(f" [LOG] multiply result: {result}")36 return result3738# Class inheritance forwarding #?classforward39class Button:40 def __init__(self, text, **options): #?baseinit41 self.text = text42 self.options = options43 print(f" Button created: '{text}' with {options}")4445class FancyButton(Button):46 def __init__(self, text, **options): #?derivedinit47 # Add default options48 options.setdefault('border', True)49 # Forward to parent50 super().__init__(text, **options)51 print(" (FancyButton enhancements applied)")output (FancyButton enhancements applied)main()
53if __name__ == "__main__":54 main()55#@help forward
Wrapper functions use *args, **kwargs to forward all arguments.
Exercise: decorators.py
Use *args/**kwargs in decorator functions