از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
آرگومان های با طول متغیر در پایتون با *args و **kwargs
سرفصلهای مطلب
معرفی
برخی از توابع هیچ آرگومان ندارند، برخی دیگر دارای چندین آرگومان هستند. مواقعی وجود دارد که ما توابعی با آرگومان هایی داریم که از قبل از آنها بی اطلاعیم. ممکن است تعدادی آرگومان متغیر داشته باشیم زیرا می خواهیم یک 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()
. این استدلال ها با موقعیت آنها پردازش می شود. اگر بخواهیم چندین آرگومان بگیریم، اما آنها را با نامشان ارجاع دهیم، چه؟ در بخش بعدی روش انجام این کار را بررسی خواهیم کرد.
استفاده از بسیاری از آرگومان های نامگذاری شده با **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'}
هنگام اختلاط آرگومان های موقعیتی و نامگذاری شده، آرگومان های موضعی باید بیایند قبل از آرگومان های نامگذاری شده علاوه بر این، آرگومان های با طول ثابت قبل از آرگومان هایی با طول متغیر قرار می گیرند. بنابراین، سفارشی مانند این دریافت می کنیم:
- استدلال های موضعی شناخته شده
*args
- آرگومان های با نام شناخته شده
**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