🐍 کتابخانه مرجع پایتون

🎯 *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="saba@example.com")
⏳ برای اجرا دکمه را بزنید...

🔹 مثال جامع: سیستم گزارش‌گیری

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)
⏳ برای اجرا دکمه را بزنید...

📌 نکات کلیدی

← قبلی: توابع لامبدا → بعدی: فهرست مقدماتی ↑ بازگشت به فهرست مقدماتی