Arguments are the lifeblood of functions in Python. They provide a way to pass data into functions, allowing them to be flexible and reusable. However, with different types of arguments, understanding how they work becomes crucial. In this blog, we will discuss the various argument types in Python and how to use them effectively. We will use detailed bank account examples using classes, inheritance, and multiple inheritance to get a better practical understanding of how to work with arguments.
Types of Arguments in Python
- Positional Arguments
- Keyword Arguments
- Default Arguments
- Variable-Length Arguments (Arbitrary Arguments)
- *args (Non-Keyword Variable-Length Arguments)
- **kwargs (Keyword Variable-Length Arguments)
Let's explore each of these with examples.
1. Positional Arguments
These are the most basic type of arguments. Their order matters! When defining a function, you specify variables within the parentheses after the function name. These variables become placeholders for the values you'll pass during the function call. The order in which you provide the values during the call should match the order of the variables defined in the function.
def greet(name, age):
print(f"Hello, {name}! You are {age} years old.")
greet("Alice", 30) # Output: Hello, Alice! You are 30 years old.
Here, "name" and "age" are positional arguments. "Alice" is assigned to "name" and 30 to "age" because they appear in the same order during the function call.
2. Keyword Arguments
With positional arguments, order is important. Keyword arguments break free from this constraint. You can pass arguments by name during the function call, regardless of their position in the definition.
def describe(name, age):
print(f"{name} is {age} years old.")
describe(age=35, name="David") # Order doesn't matter here!
Here, the order of arguments doesn't matter because we are using keyword arguments.
3. Default Arguments
Imagine a function where some arguments have pre-defined values. This is where default arguments come in. You can assign a default value to a parameter in the function definition. If no value is provided during the call, the default value is used.
def greet(name, age=25): # "age" has a default value of 25
print(f"Hello, {name}! You are {age} years old.")
greet("Bob") # Output: Hello, Bob! You are 25 years old. (Uses default age)
greet("Charlie", 40) # Output: Hello, Charlie! You are 40 years old.
4. Arbitrary Arguments/Variable-Length Arguments (**args and **kwargs)
What if you need a function to handle a varying number of arguments? Enter arbitrary arguments! Variable-length arguments allow you to pass an arbitrary number of arguments to a function. There are two types:
- *args (arbitrary positional arguments): Captures any number of positional arguments as a tuple within the function.
- **kwargs (arbitrary keyword arguments): Captures any number of keyword arguments as a dictionary within the function.
*args (Non-Keyword Variable-Length Arguments)
*args allows a function to accept any number of positional arguments.
class BankAccount:
def __init__(self, account_number, account_holder, *transactions):
self.account_number = account_number
self.account_holder = account_holder
self.transactions = transactions
def display_info(self):
print(f"Account Number: {self.account_number}")
print(f"Account Holder: {self.account_holder}")
print("Transactions:", self.transactions)
# Example Usage
account = BankAccount("123456", "Alice", 100, -50, 200, -30)
account.display_info()
Here, *transactions collects all additional positional arguments into a tuple.
**kwargs (Keyword Variable-Length Arguments)
**kwargs allows a function to accept any number of keyword arguments.
class BankAccount:
def __init__(self, account_number, account_holder, **kwargs):
self.account_number = account_number
self.account_holder = account_holder
self.details = kwargs
def display_info(self):
print(f"Account Number: {self.account_number}")
print(f"Account Holder: {self.account_holder}")
print("Additional Details:", self.details)
# Example Usage
account = BankAccount("123456", "Alice", address="123 Main St", phone="555-1234")
account.display_info()
In this example, **kwargs collects all additional keyword arguments into a dictionary.
Taking Advanced Examples and applying them to Inheritance
Let's extend our examples using classes, inheritance, and multiple inheritance to demonstrate these argument types in more complex scenarios.
Single Inheritance
class BankAccount:
def __init__(self, account_number, account_holder, balance=0.0):
self.account_number = account_number
self.account_holder = account_holder
self.balance = balance
def display_info(self):
print(f"Account Number: {self.account_number}")
print(f"Account Holder: {self.account_holder}")
print(f"Balance: {self.balance}")
class SavingsAccount(BankAccount):
def __init__(self, account_number, account_holder, balance=0.0, interest_rate=0.01):
super().__init__(account_number, account_holder, balance)
self.interest_rate = interest_rate
def display_info(self):
super().display_info()
print(f"Interest Rate: {self.interest_rate}")
# Example Usage
savings_account = SavingsAccount("123456", "Alice", 1000.0, interest_rate=0.02)
savings_account.display_info()
In this example, SavingsAccount inherits from BankAccount and adds an interest_rate parameter.
Multiple Inheritance
class AccountHolder:
def __init__(self, name, address):
self.name = name
self.address = address
def display_holder_info(self):
print(f"Name: {self.name}")
print(f"Address: {self.address}")
class BankAccount:
def __init__(self, account_number, balance=0.0):
self.account_number = account_number
self.balance = balance
def display_account_info(self):
print(f"Account Number: {self.account_number}")
print(f"Balance: {self.balance}")
class BusinessAccount(AccountHolder, BankAccount):
def __init__(self, name, address, account_number, balance=0.0, business_name=""):
AccountHolder.__init__(self, name, address)
BankAccount.__init__(self, account_number, balance)
self.business_name = business_name
def display_info(self):
self.display_holder_info()
self.display_account_info()
print(f"Business Name: {self.business_name}")
# Example Usage
business_account = BusinessAccount("Alice", "123 Main St", "123456", 5000.0, business_name="Alice's Bakery")
business_account.display_info()
In this example, BusinessAccount inherits from both AccountHolder and BankAccount, demonstrating multiple inheritance.
Conclusion
Understanding the different types of arguments in Python functions is essential for writing flexible and powerful code. Whether you're dealing with simple positional arguments or complex variable-length arguments, Python provides the tools you need. By applying these concepts in practical examples, such as bank account management with classes and inheritance, you can see the power and flexibility of Python in action. Happy coding!