وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

آرگومان های با طول متغیر در پایتون با *args و **kwargs

0 100
زمان لازم برای مطالعه: 6 دقیقه


معرفی

برخی از توابع هیچ آرگومان ندارند، برخی دیگر دارای چندین آرگومان هستند. مواقعی وجود دارد که ما توابعی با آرگومان هایی داریم که از قبل از آنها بی اطلاعیم. ممکن است تعدادی آرگومان متغیر داشته باشیم زیرا می خواهیم یک API انعطاف پذیر به توسعه دهندگان دیگر ارائه دهیم یا اندازه ورودی را نمی دانیم. با پایتون می‌توانیم توابعی برای پذیرش هر مقدار آرگومان ایجاد کنیم.

در این مقاله به روش تعریف و استفاده از توابع با آرگومان های طول متغیر خواهیم پرداخت. این توابع می توانند مقدار نامعلومی از ورودی را بپذیرند، چه به عنوان ورودی های متوالی و چه به عنوان آرگومان های نامگذاری شده.

استفاده از بسیاری از آرگومان ها با *args

بیایید تابعی را پیاده سازی کنیم که حداقل مقدار را بین دو عدد پیدا کند. به این صورت خواهد بود:

def my_min(num1, num2):
    if num1 < num2:
        return num1
    return num2

my_min(23, 50)
23

این به سادگی بررسی می کند که آیا عدد اول کوچکتر از عدد دوم است یا خیر. اگر اینطور باشد، اولین شماره برگردانده می شود. در غیر این صورت شماره دوم برگردانده می شود.

اگر می‌خواهیم حداقل 3 عدد پیدا کنیم، می‌توانیم آرگومان دیگری به آن اضافه کنیم my_min() و بیانیه های اگر. اگر تابع حداقل ما نیاز به یافتن کمترین عدد از هر مقدار نامشخص داشته باشد، می توانیم از یک لیست استفاده کنیم:

def my_min(nums):
    result = nums(0)
    for num in nums:
        if num < result:
            result = num
    return result

my_min((4, 5, 6, 7, 2))
2

در حالی که این کار می کند، کدگذاران ما اکنون باید اعداد خود را در لیستی قرار دهند، که به سادگی زمانی که دو یا سه آرگومان تعریف شده داشتیم نیست. بیایید بهترین هر دو جهان را با آرگومان های طول متغیر بدست آوریم.

آرگومان های با طول متغیر، به اختصار varargs، آرگومان هایی هستند که می توانند مقدار نامشخصی ورودی بگیرند. هنگامی که از اینها استفاده می شود، برنامه نویس نیازی به قرار دادن داده ها در یک لیست یا یک دنباله جایگزین ندارد.

در پایتون، vararg ها با استفاده از عبارت تعریف می شوند *args نحو. بیایید خود را دوباره پیاده سازی کنیم my_min() عملکرد با *args:

def my_min(*args):
    result = args(0)
    for num in args:
        if num < result:
            result = num
    return result

my_min(4, 5, 6, 7, 2)
2

توجه داشته باشید: args فقط یک نام است، شما می توانید آن vararg را تا زمانی که یک ستاره قبل از آن وجود دارد نامگذاری کنید (*). بهترین تمرین این است که به نامگذاری آن ادامه دهید args تا فورا قابل تشخیص باشد.

هر بحثی که بعد از آن بیاید *args باید یک آرگومان با نام باشد – آرگومانی که به جای موقعیتش با نام آن ارجاع داده می شود. با *args شما دیگر نمی توانید به آرگومان دیگری با موقعیت آن ارجاع دهید.

همچنین، شما فقط می توانید داشته باشید روی *args vararg را در یک تابع تایپ کنید.

ممکن است فکر کنید که راه حل با *args بسیار شبیه به راه حل لیست است. به این دلیل است *args در داخل یک تاپل است، که یک دنباله تکرارپذیر شبیه به لیست است. اگر می خواهید نوع آن را تأیید کنید، می توانید کد را در مفسر پایتون خود وارد کنید:

$ python3
>>> def arg_type_test(*args):
...     print(type(args))
...
>>> arg_type_test(1, 2)
<class 'tuple'>

با *args، می توانیم چندین آرگومان را به ترتیب بپذیریم همانطور که در انجام می شود my_min(). این استدلال ها با موقعیت آنها پردازش می شود. اگر بخواهیم چندین آرگومان بگیریم، اما آنها را با نامشان ارجاع دهیم، چه؟ در بخش بعدی روش انجام این کار را بررسی خواهیم کرد.

پیشنهاد می‌کنیم بخوانید:  نحوه ساخت اپلیکیشن تخته سفید با پایتون و Tkinter

استفاده از بسیاری از آرگومان های نامگذاری شده با **kwargs

پایتون می تواند چندین مورد را بپذیرد آرگومان های کلمه کلیدی، بیشتر به عنوان شناخته شده است **kwargs. رفتاری مشابه دارد *args، اما آرگومان ها را به جای تاپل ها در فرهنگ لغت ذخیره می کند:

def kwarg_type_test(**kwargs):
    print(kwargs)

kwarg_type_test(a="hi")
kwarg_type_test(roses="red", violets="blue")

خروجی خواهد بود:

{'a': 'hi'}
{'roses': 'red', 'violets': 'blue'}

با استفاده از دیکشنری، **kwargs می تواند نام استدلال ها را حفظ کند، اما نمی تواند جایگاه آنها را حفظ کند.

توجه داشته باشید: پسندیدن args، می توانید از هر نام دیگری غیر از kwargs. با این حال، بهترین تمرین حکم می کند که باید به طور مداوم از آن استفاده کنید kwargs.

از آنجا که **kwargs یک فرهنگ لغت است، می توانید مانند هر فرهنگ دیگری با استفاده از آن، روی آنها تکرار کنید .items() روش:

def kwargs_iterate(**kwargs):
    for i, k in kwargs.items():
        print(i, '=', k)

kwargs_iterate(hello='world')

هنگام اجرا، ما console نشان خواهد داد:

hello = world

آرگومان های کلیدواژه زمانی مفید هستند که مطمئن نیستید آرگومان در دسترس است یا خیر. به عنوان مثال، اگر عملکردی برای ذخیره یک پست وبلاگ در پایگاه داده داشته باشیم، اطلاعاتی مانند محتوا و نویسنده را ذخیره می کنیم. یک پست وبلاگ ممکن است برچسب‌ها و دسته‌هایی داشته باشد، اگرچه اینها همیشه تنظیم نمی‌شوند.

ما می توانیم تابعی مانند این تعریف کنیم:

def save_blog_post(content, author, tags=(), categories=()):
    pass

از طرف دیگر، ما به فراخوان تابع اجازه می‌دهیم تا هر مقداری از آرگومان‌ها را ارسال کند و فقط مرتبط شود tags و categories اگر تنظیم شده باشند:

def save_blog_post(content, author, **kwargs):
    if kwargs.get('tags'):
        
        pass

    if kwargs.get('categories'):
        
        pass

اکنون که هر دو نوع پشتیبانی از آرگومان های طول متغیر را درک می کنیم، بیایید ببینیم چگونه می توانیم این دو را در یک تابع ترکیب کنیم.

ترکیب Varargs و Arguments کلیدواژه

اغلب ما می خواهیم از هر دو استفاده کنیم *args و **kwargs با هم، به خصوص هنگام نوشتن کتابخانه های پایتون یا کدهای قابل استفاده مجدد. خوش شانس برای ما، *args و **kwargs به خوبی با هم بازی کنید، و ما می توانیم از آنها به روش زیر استفاده کنیم:

def combined_varargs(*args, **kwargs):
    print(args)
    print(kwargs)

combined_varargs(1, 2, 3, a="hi")

اگر آن قطعه کد را اجرا کنید، خواهید دید:

(1, 2, 3)
{'a': 'hi'}

هنگام اختلاط آرگومان های موقعیتی و نامگذاری شده، آرگومان های موضعی باید بیایند قبل از آرگومان های نامگذاری شده علاوه بر این، آرگومان های با طول ثابت قبل از آرگومان هایی با طول متغیر قرار می گیرند. بنابراین، سفارشی مانند این دریافت می کنیم:

  1. استدلال های موضعی شناخته شده
  2. *args
  3. آرگومان های با نام شناخته شده
  4. **kwargs

یک تابع با انواع آرگومان ها می تواند به شکل زیر باشد:

def super_function(num1, num2, *args, callback=None, messages=(), **kwargs):
    pass

هنگامی که هنگام تعریف و فراخوانی توابع با آرگومان های varargs و کلیدواژه از این ترتیب پیروی می کنیم، رفتاری را که از آنها انتظار داریم دریافت خواهیم کرد.

پیشنهاد می‌کنیم بخوانید:  آرگومان های خط فرمان در پایتون

تا کنون ما استفاده کرده ایم *args و **kwargs نحو برای تعاریف توابع پایتون به ما این امکان را می دهد که هنگام فراخوانی توابع نیز از همان نحو استفاده کنیم. بیایید ببینیم چگونه!

باز کردن آرگومان ها با *args و **kwargs

بیایید یک تابع را در نظر بگیریم add3()، که 3 عدد را می پذیرد و مجموع آنها را چاپ می کند. ما می توانیم آن را به شکل زیر ایجاد کنیم:

def add3(num1, num2, num3):
    print("The grand total is", num1 + num2 + num3)

اگر لیستی از اعداد داشتید، می توانید از این تابع با تعیین اینکه کدام آیتم لیست به عنوان آرگومان استفاده می شود استفاده کنید:

magic_nums = (32, 1, 7)

add3(magic_nums(0), magic_nums(1), magic_nums(2))

اگر این کد را اجرا کنید، خواهید دید:

The grand total is 40

در حالی که این کار می کند، ما می توانیم این را مختصرتر کنیم *args نحو:

add3(*magic_nums)

خروجی است The grand total is 40، درست مثل قبل

وقتی استفاده می کنیم *args نحو در فراخوانی تابع، ما هستیم باز کردن بسته بندی متغیر منظور ما از باز کردن بسته‌بندی این است که مقادیر فردی فهرست را بیرون می‌کشیم. در این حالت، هر عنصر لیست را بیرون می آوریم و آنها را در آرگومان ها قرار می دهیم، جایی که موقعیت 0 با آرگومان اول مطابقت دارد.

شما همچنین می توانید به طور مشابه یک تاپل را باز کنید:

tuple_nums = (32, 1, 7)
add3(*tuple_nums) 

اگر می خواهید یک دیکشنری را باز کنید، باید از آن استفاده کنید **kwargs نحو.

dict_nums = {
    'num1': 32,
    'num2': 1,
    'num3': 7,
}

add3(**dict_nums) 

در این حالت، پایتون کلید دیکشنری را با نام آرگومان مطابقت داده و مقدار آن را تعیین می کند.

و بس! شما می توانید به جای تعیین هر آرگومان که به مقداری از یک شی نیاز دارد، با بازکردن مقادیر، فراخوانی های تابع خود را آسان تر مدیریت کنید.

نتیجه

با پایتون می توانیم از *args یا **kwargs سینتکس برای گرفتن تعداد متغیری از آرگومان ها در توابع ما. استفاده کردن *args، ما میتوانیم process تعداد نامحدودی از آرگومان ها در موقعیت یک تابع. با **kwargs، می توانیم تعداد نامحدودی از آرگومان ها را با نام آنها بازیابی کنیم.

در حالی که یک تابع فقط می تواند یک آرگومان با طول متغیر از هر نوع داشته باشد، ما می توانیم هر دو نوع تابع را در یک آرگومان ترکیب کنیم. اگر این کار را انجام دهیم، باید اطمینان حاصل کنیم که آرگومان های موقعیتی قبل از آرگومان های نامگذاری شده و آرگومان های ثابت قبل از آرگومان های با طول متغیر قرار می گیرند.

پایتون به ما این امکان را می دهد که از سینتکس برای فراخوانی تابع نیز استفاده کنیم. اگر لیست یا تاپلی داشته باشیم و از آن استفاده کنیم *args نحو، هر مقدار را به عنوان آرگومان های موقعیتی باز می کند. اگر فرهنگ لغت داشته باشیم و استفاده کنیم **kwargs نحو، سپس نام کلیدهای فرهنگ لغت را با نام آرگومان های تابع مطابقت می دهد.

کار میکنی روی تابعی که می تواند از این نوع آرگومان ها بهره مند شود؟ یا شاید شما می توانید یک تابع را refactor کنید و آن را اثبات آینده کنید؟ به ما اطلاع دهید که دارید کار می کنید روی!

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-18 15:31:05

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید