🎯 *args و **kwargs در پایتون
*args و **kwargs به شما امکان میدهند توابعی بنویسید که تعداد نامعینی از آرگومانها را بپذیرند.
این ویژگی برای زمانی که تعداد آرگومانها از قبل مشخص نیست، بسیار مفید است.
🔹 *args (آرگومانهای موقعیتی نامعین)
*args به شما اجازه میدهد تعداد نامعینی آرگومان موقعیتی را به تابع ارسال کنید.
# تابعی که هر تعداد عدد را جمع میکند
def sum_all(*args):
total = 0
for num in args:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(10, 20, 30, 40)) # 100
print(sum_all(5, 10)) # 15
print(sum_all()) # 0
⏳ برای اجرا دکمه را بزنید...
🔹 مشاهده محتوای *args
def show_args(*args):
print(f"Number of arguments: {len(args)}")
print(f"Arguments: {args}")
for i, arg in enumerate(args):
print(f" arg[{i}] = {arg}")
show_args(10, "hello", 3.14, True)
⏳ برای اجرا دکمه را بزنید...
🔹 ترکیب *args با پارامترهای عادی
# پارامترهای عادی قبل از *args قرار میگیرند
def introduce(greeting, *names):
for name in names:
print(f"{greeting}, {name}!")
introduce("Hello", "Saba", "Ali", "Reza")
introduce("Hi", "Mina")
⏳ برای اجرا دکمه را بزنید...
🔹 **kwargs (آرگومانهای کلیدی نامعین)
**kwargs به شما اجازه میدهد تعداد نامعینی آرگومان کلیدی (key-value) را به تابع ارسال کنید.
# تابعی که اطلاعات شخصی را نمایش میدهد
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Saba", age=28, city="Tehran")
print("\n")
print_info(product="Laptop", price=1200, brand="Dell", in_stock=True)
⏳ برای اجرا دکمه را بزنید...
🔹 مشاهده محتوای **kwargs
def show_kwargs(**kwargs):
print(f"Number of keyword arguments: {len(kwargs)}")
print(f"Keyword arguments: {kwargs}")
for key, value in kwargs.items():
print(f" {key} = {value}")
show_kwargs(name="Saba", age=28, city="Tehran")
⏳ برای اجرا دکمه را بزنید...
🔹 ترکیب *args و **kwargs
ترتیب: پارامترهای عادی، *args، سپس **kwargs
def show_all(a, b, *args, **kwargs):
print(f"a = {a}")
print(f"b = {b}")
print(f"args = {args}")
print(f"kwargs = {kwargs}")
show_all(1, 2, 3, 4, 5, name="Saba", age=28)
⏳ برای اجرا دکمه را بزنید...
🔹 باز کردن (Unpacking) با * و **
# تعریف تابع print_info
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
# باز کردن لیست با *
numbers = [1, 2, 3, 4, 5]
print(*numbers) # معادل print(1, 2, 3, 4, 5)
# باز کردن دیکشنری با **
person = {"name": "Saba", "age": 28, "city": "Tehran"}
print_info(**person) # معادل print_info(name="Saba", age=28, city="Tehran")
⏳ برای اجرا دکمه را بزنید...
🔹 استفاده از *args و **kwargs برای فراخوانی توابع دیگر
def sum_numbers(a, b, c):
return a + b + c
def wrapper(*args, **kwargs):
# ارسال آرگومانها به تابع دیگر
result = sum_numbers(*args, **kwargs)
return result
print(wrapper(1, 2, 3)) # 6
# با استفاده از kwargs
def multiply(a=1, b=1, c=1):
return a * b * c
def wrapper2(**kwargs):
return multiply(**kwargs)
print(wrapper2(a=2, b=3, c=4)) # 24
⏳ برای اجرا دکمه را بزنید...
🔹 کاربرد در دکوریتورها
# دکوریتور ساده برای نمایش زمان اجرا
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"Function {func.__name__} took {end - start:.4f} seconds")
return result
return wrapper
@timer
def slow_function():
time.sleep(0.5)
print("Function executed!")
@timer
def sum_all(*args):
return sum(args)
slow_function()
result = sum_all(1, 2, 3, 4, 5)
print(f"Result: {result}")
⏳ برای اجرا دکمه را بزنید...
🔹 نکات و ترفندها
# ۱. نامها میتوانند متفاوت باشند (اما بهتر است از args و kwargs استفاده کنید)
def my_function(*numbers, **options):
print(f"Numbers: {numbers}")
print(f"Options: {options}")
my_function(1, 2, 3, color="red", size="large")
# ۲. استفاده از *args برای ورودی کاربر
def get_average(*grades):
if not grades:
return 0
return sum(grades) / len(grades)
print(get_average(18, 19, 17, 20)) # 18.5
# ۳. ترکیب با پارامترهای پیشفرض
def create_user(username, *args, is_active=True, **kwargs):
print(f"Username: {username}")
print(f"Args: {args}")
print(f"Is active: {is_active}")
print(f"Kwargs: {kwargs}")
create_user("saba77", 28, "Tehran", is_active=False, email="[email protected]")
⏳ برای اجرا دکمه را بزنید...
🔹 مثال جامع: سیستم گزارشگیری
import datetime
class ReportGenerator:
def __init__(self, title):
self.title = title
self.entries = []
def add_entry(self, *args, **kwargs):
"""اضافه کردن یک ورود به گزارش"""
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
entry = {
"timestamp": timestamp,
"args": args,
"kwargs": kwargs
}
self.entries.append(entry)
print(f"Entry added at {timestamp}")
def generate_report(self, *sections, **formatting):
"""تولید گزارش با بخشهای مشخص"""
print("=" * 50)
print(f"Report: {self.title}")
print("=" * 50)
# استفاده از *sections برای بخشهای گزارش
for section in sections:
print(f"\n--- {section} ---")
if section == "summary":
print(f"Total entries: {len(self.entries)}")
elif section == "details":
for i, entry in enumerate(self.entries):
print(f"\nEntry {i+1}:")
print(f" Time: {entry['timestamp']}")
print(f" Args: {entry['args']}")
print(f" Kwargs: {entry['kwargs']}")
elif section == "stats":
# استفاده از **formatting برای تنظیمات
show_timestamps = formatting.get("show_timestamps", True)
print(f"Statistics (show timestamps: {show_timestamps})")
# آمار ساده
print(f" Number of entries: {len(self.entries)}")
print("\n" + "=" * 50)
# استفاده
report = ReportGenerator("Daily Activity Report")
# افزودن ورودیها
report.add_entry("User logged in", user="saba", ip="192.168.1.1")
report.add_entry("File uploaded", "document.pdf", size="2MB", status="success")
report.add_entry("Data processed", records=100, duration="0.5s")
# تولید گزارش با بخشهای مختلف
report.generate_report("summary", "details", "stats", show_timestamps=True)
# تولید گزارش با بخشهای مختلف و تنظیمات متفاوت
print("\n" + "=" * 50)
print("Another report with different sections:")
report.generate_report("summary", "stats", show_timestamps=False)
⏳ برای اجرا دکمه را بزنید...
📌 نکات کلیدی
- ✅
*argsبرای دریافت تعداد نامعین آرگومان موقعیتی استفاده میشود. - ✅
**kwargsبرای دریافت تعداد نامعین آرگومان کلیدی استفاده میشود. - ✅ نامها میتوانند متفاوت باشند (اما
argsوkwargsاستاندارد هستند). - ✅ ترتیب: پارامترهای عادی، سپس
*args، سپس**kwargs. - ✅ با
*میتوانید لیستها را باز کنید. - ✅ با
**میتوانید دیکشنریها را باز کنید. - ✅ در دکوریتورها،
*argsو**kwargsبسیار مفید هستند. - ✅ این قابلیت به انعطافپذیری و قابلیت استفاده مجدد کد کمک میکند.