میتوانیم تابعی ایجاد کنیم که توالی فیبوناچی را تا یک مرز دلخواه بنویسد:
>>> def fib(n): # نوشتن توالی فیبوناچی کمتر از n ... """چاپ توالی فیبوناچی کمتر از n.""" ... a, b = 0, 1 ... while a < n: ... print(a, end=' ') ... a, b = b, a+b ... print() ... >>> # حالا تابعی را که تازه تعریف کردیم فراخوانی کنید: >>> fib(2000) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
کلمه کلیدی def یک تعریف تابع را معرفی میکند. باید با نام تابع و لیست پرانتزدار پارامترهای رسمی دنبال شود. عباراتی که بدنه تابع را تشکیل میدهند از خط بعد شروع میشوند و باید تورفتگی داشته باشند.
اولین عبارت بدنه تابع به طور اختیاری میتواند یک لیترال رشتهای باشد؛ این لیترال رشتهای رشته مستندات یا docstring تابع است. (اطلاعات بیشتر درباره docstrings در بخش «رشتههای مستندات» یافت میشود.) ابزارهایی وجود دارند که از docstrings برای تولید خودکار مستندات آنلاین یا چاپی استفاده میکنند، یا به کاربر اجازه میدهند به صورت تعاملی از کد عبور کند؛ خوب است docstrings را در کدی که مینویسید درج کنید، پس عادت کنید.
اجرا یک تابع یک جدول نماد جدید برای متغیرهای محلی تابع معرفی میکند. دقیقتر، تمام اختصاصهای متغیر در یک تابع، مقدار را در جدول نماد محلی ذخیره میکنند؛ در حالی که مراجع به متغیر ابتدا در جدول نماد محلی، سپس در جداول نماد توابع محصورکننده، سپس در جدول نماد سراسری و در نهایت در جدول نامهای داخلی جستجو میشوند. بنابراین، متغیرهای سراسری و متغیرهای توابع محصورکننده نمیتوانند مستقیماً در یک تابع مقداردهی شوند (مگر اینکه برای متغیرهای سراسری، در دستور global نام برده شوند، یا برای متغیرهای توابع محصورکننده، در دستور nonlocal نام برده شوند)، اگرچه میتوان به آنها مراجعه کرد.
پارامترهای واقعی (آرگومانها) در فراخوانی تابع، هنگام فراخوانی در جدول نماد محلی تابع فراخوانی شده معرفی میشوند؛ بنابراین، آرگومانها با فراخوانی با مقدار (call by value) منتقل میشوند (جایی که مقدار همیشه یک مرجع شیء است، نه مقدار خود شیء) [۱]. وقتی یک تابع تابع دیگری را فراخوانی میکند، یا به طور بازگشتی خود را فراخوانی میکند، یک جدول نماد محلی جدید برای آن فراخوانی ایجاد میشود.
تعریف تابع، نام تابع را با شیء تابع در جدول نماد جاری پیوند میدهد. مفسر شیءای که توسط آن نام اشاره میشود را به عنوان تابع تعریفشده توسط کاربر بازشناسی میکند. نامهای دیگر نیز میتوانند به همان شیء تابع اشاره کنند و برای دسترسی به تابع استفاده شوند:
>>> fib>>> f = fib >>> f(100) 0 1 1 2 3 5 8 13 21 34 55 89
شما که از زبانهای دیگر آمدهاید، ممکن است اعتراض کنید که fib یک تابع نیست بلکه procedure است زیرا مقداری برنمیگرداند. در واقع، حتی توابع بدون دستور return نیز مقداری برمیگردانند، هرچند نسبتاً خستهکننده. این مقدار None نامیده میشود (یک نام داخلی است). نوشتن مقدار None معمولاً توسط مفسر سرکوب میشود اگر تنها مقدار نوشته شده باشد. میتوانید آن را با استفاده از print() ببینید:
>>> fib(0) >>> print(fib(0)) None
نوشتن تابعی که لیستی از اعداد توالی فیبوناچی را برگرداند، به جای چاپ آن، ساده است:
>>> def fib2(n): # برگرداندن توالی فیبوناچی تا n ... """برگرداندن لیستی حاوی توالی فیبوناچی تا n.""" ... result = [] ... a, b = 0, 1 ... while a < n: ... result.append(a) # در ادامه بیشتر خواهیم دید ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) # فراخوانی >>> f100 # نمایش نتیجه [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
این مثال، مانند همیشه، چندین ویژگی جدید پایتون را نشان میدهد:
return با مقداری از تابع برمیگردد. return بدون آرگومان عبارتی، None برمیگرداند. افتادن از انتهای تابع نیز None برمیگرداند.result.append(a) یک متد شیء لیست result را فراخوانی میکند. متد تابعی است که به یک شیء «تعلق» دارد و به صورت obj.methodname نامگذاری میشود، که در آن obj یک شیء است و methodname نام متدی است که توسط نوع شیء تعریف شده است. انواع مختلف متدهای مختلفی تعریف میکنند. متدهای انواع مختلف میتوانند نام یکسانی داشته باشند بدون ایجاد ابهام. متد append() در مثال برای اشیاء لیست تعریف شده است و یک عنصر جدید در انتهای لیست اضافه میکند. در این مثال معادل result = result + [a] است، اما کارآمدتر.این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://docs.python.org/3/tutorial