نویسنده مطلب: مسعود شریفی
سایت منتشر کننده مطلب: ام اس پی سایت
مقدمه
و اما چرا باید از پایتون استفاده کنیم ؟؟
پایتون شی گراست
پایتون زاتا یک زبان شز گراست و از ویژگی های پیشرفته شی گرایی چون وراثت – چند شکلی – سربار گزاری عملگر و … پشتیبانی می کند اگر شما با برنامه نویسی شی گرا آشنایی ندارید پایتون یک راه حل عالی واسه یاد گرفتنشه !!! نکته جالب و یک ویژگی منحصر به فرد پایتون که لقب چسب را بارای پایتون به ارمغان آورده امکان استفاده از کد ها و کلاس های نوشته شده در زبانهای دیگری چون ++ C و Java هستش و یه جورایی کار چسباندن قطعات کد جدا و فقط نوشتن بدنه اصلی به عهده پایتون است .
پایتون رایگان است !!
پایتون یک زبان رایگان و باز متن هستش که این روزا بحث اکثر محافل شده .
با کمی توجه به این نکته که دیر یا زود قانون کپی رایت (اون طوری که من از
منابع موثق شنیدم ۲ سال بعد !!)می یاد و فکر نمی کنم تو کشوری مثل ایران و
پس از جوی مثل الان کسی حاضر بشه یه نر افزار رو با قیمت واقعی اون بخره (
مثلا ۱۰۰ هزار تومن واسه ویندوز !!) پس می شه گفت تها گزینه واسه ما نرم
افزار های باز متن و رایگان هستش البته تنها دلیل رایگان بودت این دسته از
نرم افزار ها نیستش . موضوعات مهم دیگری هم هست که خودشون یه مقاله جدا
هستن …
پایتون یک زبان پورتابل یا قابل انتقال می باشد :
چون پایتون با زبان پورتابل C نوشته شده می تواند به صورت مجازی بر روی هر
سیستمی کامپایل و اجرا شود . اگه یادتون باشه گفتم این یه زبان اسکریپتی
یعنی در حالت معمول به فایل اجرایی تبدیل نمی شه بلکه یک ماشین مجازی فایل
کد رو می خونه و همزمان اونارو تفسیر کرده و اجرا می کنه . پس شما می تونید
یک برنامه رو تو ویندوز بنویسید و سپس انو بدون تغییر روی لینوکس یا
مکینتاش یا هر سیستم عامل و سخت افزار دیگری که پایتون روی آن نصب باشد
اجرا کنید .
پایتون قدرتمند است
پایتون یه زبان چند رگه هستش . پایتون از زبانهای اسکریپتی (برای مثال :
Tcl , Scheme , Perl) و زبانهای سیستمی (برای مثال : C++ , C و Java )
مشتق شده . بنابراین تمام سادگی و راحتی کار زبان های اسکریپتی و ویژگی ها و
قدرت زباهای سطح پایین را داراست .
پایتون قابلیت استفاده از کد های نوشته شده با سایر زبان ها را دارد :
این ویژگی یکی از پرکاربرد ترین و قوی ترین ویژگی های پایتون می باشد . شما
می توانید قطعه از کد را در زبانی چون C , C++ و Java نوشت اونو تبدیل به
فایل اجرایی کرد و سپس ازش در برنامه نوشته شده با پایتون استفاده کرد . و
یا از توابع کتابخانه و کامپوننت هایی چون COM API استفاده کرد .
یادگیری و استفاده از پایتون بسیار راحت می باشد
بی شک و حداقل از نظر من و بسیاری از برنامه نویسان پایتون این زبان یکی از آسان ترین زبان ها برای یادگیری و استفاده می باشد و از آن به عنوان یک زبان سریع برنامه نویسی یاد می کنند . این زبان نیازی به کامپایل ندارد و شما مستقما می توانید پس از نوشتد کد و با یک دستور آن را اجرا کنید . دستورات این زبان بسیار نزدیک به زبان انسان می باشد . برای مثال برنامه Hello World را که اولین برنامه ساده می باشد را در دو زبان C و Python مقایسه کنید :
#include <stdio.h>
int main()
{
printf("Hello World ");
return 0;
}
ابتدا باید این برنامه را بنویسید و آن را یا دستوری چون cc helloworld.c -o hello کامپایل و سپس با دستور hello/. اونو اجرا کنید . اما بوسیله پایتون در یک فایل متنی بنویسید :
print "Hello World !!"
و با دستور python hi.py اونو اجرا کنید .
با کم شدن حجم کد برنامه نویسی راحت تر و رفع اشکال و توسعه آن آسان تر می شود .
اهمیت پایتون
مطمن هستم با اهمیت لینوکس و نرم افزار های باز متن در ایران آشنا هستید
همانطور که می دانید سیستم عامل ملی ما بر پایه لینوکس می باشد و این
لازمه توسع برنامه نویسی تحت لینوکس را برایمان آشکار می کند . شاید فکر
کنید زبان برنامه نویسی و انتخاب اکثر لینوکس کاران C می باشد این تفکر
درستی است اما نه برای برنامه هلی کاربردی مانند یک برنامه حسابداری .
پایتون در سراسر دنیا از اهمیت ویژهای برخوردار می باشد و رفته رفته به
جایگاه اصلی و لایق خود نزدیک می شود . جالب است بدانید مایکرو سافت نیز
این زبان را با نام IronPython در تکنولوژی Net. خود گنجانده است !!
به نظر من وظیفه ما این است که با تلاش و همکاریکشورمون ایران رو نیز به جایگاهی که باید خیلی وقت پیش آنجا می بودیم پیش ببریم .
آشنایی با پایتون
یه توضیح کوچولو : من تمام مثال ها رو مطابق با لینوکس (FC4) می نویسم و تست می کنم و همه دستورات در این محیط هستش و راستش بخواهید آشنایی چندانی با معادلشون تو ویندوز ندارم اما اگه بخواهید و سئوالی باشه می تونم برم دنبالش و تا جایی که ممکنه یه چیزایی بنویسم . هرجا که لازم بود بگید . شما می تونید پایتون رو برای نصب تو ویندوز یا لینوکس از اینترنت و سایت خود پایتون دانلود کنید . اکثر توزیع های کنونی لینوکس یه نسخه از مفسر پایتون رو دارند .
قبلا ما از پایتون به عنوان یک زبان برنامه نویسی یاد کردیم . اما
پایتون نام یک بسته نرم افزاری به نام مفسر نیز هست که کار اصلی آن اجرای
برنامه می باشد . مفسر سطر به سطر کد برنامه ( Python ( را خوانده و همزمان
اجرا می کند . در حالت کلی یک برنامه پایتون به ۴ طریق اجرا می شود :
– به حالت محاوره ای
– به عنوان ماجول پایتون
– به عنوان فایل اسکریپت unix
– از داخل یک سیستم دیگر
– متد های خاص یک سیستم عامل
حالت محاوره ای راحترین حال اجرای کد در پایتون می باشد . کافی هست کلمه پایتون رو وارد کنید :
# python
و سپس دستورات خود را به صورت محاوره ای وارد کنید :
>>>print "Hello world!"
!Hello world
برای خروج Ctrl-D را بفشارید (Ctrl-Z در برخی سیستم عامل ها)
در حالت دوم فایلی را با پسوند py ایجاد و کد خود را درون آن بنویسید :
import sys
print sys.argv
و سپس از طریق ترمینال آن را اجرا کنید :
python test1.py –I eggs –o bacon
['test1.py', '-I', 'eggs', '-o', 'bacon']
این برنامه بسیار کوچک که با نام test.py ذخیره شده پارامتر های ورودی را به صورت یک لیست به نمایش می گذارد . دستور معادل آن در ویندوز عبارت است از :
C:\book\tests> python test1.py -i eggs -o bacon
['test1.py', '-i', 'eggs', '-o', 'bacon']
حالت سوم اجرا در حال اسکریپت می باشد . این نوع فایل متنی حالت اجرایی داراست و مشخصه آن اولین خط آن می باشد که یک مثال ساده عبارت است از :
#!/usr/bin/env python
print 'The Bright Side of Life' # comment
توضیح اینکه اولین خط این برنامه را با کامنت ( توضیحات ) اشتبا نگیرید این سطر به این معنی است که کل کد ادامه فایل را با برنامه ای که آدرس آن پس از عبارت !# آمده فرستاده و به اجرا در می آید . پس این خط آدرس فایل اجرایی مفسر پایتون به همراه علامت های !# است . سپس این فایل را به حالت اجرایی تبدیل کرده و اجرا کنید :
chmod +x test2.py
test2.py/.
The Bright Side of Life
خوب فکر می کنم تا این حد کافی باشه لازم به ذکر هستش که روی دستورات ساده و بدیهی زیاد وقت نمی ذاریم و یکم سریع جلو می ریم تا زود تر به مثال های عملی و به درد بخور تر برسیم .
عبارات
– عبارات و انجام محاسبات ریاضی بسیار شبیه سایر زبانهای برنامه نویسی می باشد
۳ + ۵
۳ + (۵*۴)
۳ ** ۲
'Hello' + 'World'
مقدار دهی متغییر ها
– نوع متغییر ها به صورت دینامیکی تعیین می شود و در طول اجرای برنامه ممکن است تغییر یابد
– متغییر ها تنها اسمی برای یک شی می باشند و همانند زبان C به یک نقطه از حافظه اشاره نمی کنند
a = 4
b = a * 4.5
c = (a+b)/2.5
a = "Hello World"
همانطور که مشاهده می کنید تعریف یک متغییر به وسیله مقدار دهی آن انجام
می شود و این نظریه درست نیست که در پایتون نیازی به تعریف متغییر نمی
باشد برای مثال استفاده از کدی مثل
Print x
باعث نمایش یک پیغام خطا خواهد شد چون متغییر x قبلا تعریف (مقداردهی)نشده است .
نکته دیگر اینکه ما در پایتون نیازی به تعیین نوع یک متغییر نداریم برای
نمونه در مثال بالا متغییر a ابتدا مقدار صحیح (int) می باشد و سپس از آن
برای نشان دادن یک رشته استفاده شده است.
شروع برنامه نویسی
رشته
رشته اولین نوع داده ای است که باهاش آشنا می شید . فرق رشته در پایتون با اکثر زبان های برنامه نویسی اینکه یک کاراکتر به عنوان یک رشته با طول یک می باشد . توضیح دیگر علامت نقل قول دوگانه و منفرد تقریبا کار یکسانی انجام می دن البته فرقهایی دارند که به مرور و با مثال آشنا خواهید شد از ۳ علامت نقل گول هم برای وارد کردن رشته هایی دارای علامت های خاص استفاده می شود.
>>> ‘Ali said “How\’re we supposed to know that?”’
‘Ali said “How\’re we supposed to know that?”’
>>> “””This is kind of a special string, because it violates some
… rules that we haven’t talked about yet”””
“This is kind of a special string, because it violates some\n rules that we
haven’t talked about yet”
فرمت بندی رشته
شبیه منطقی مانند فرمتد بندی C می باشد :
>>> “Mehdi %s” % (“ Bayazee”)
‘Mehdi Bayazee’
>>> “%-۱۰s %s %10s” % (“Name”, “Id”, “Family”)
‘Name Id Family’
>>> “Controlling the number of decimal places shown: %.02f” % ۲۵.۱۰۱۰۱۰۱۰۱
‘Controlling the number of decimal places shown: 25.10’
اعداد و عملگر ها
پایتون دارای نوع های پیش فرض integers,long numbers,floating-point(float), imaginary numbers می باشد . برای اطلاع از نوع یک متغییر در هر لحظحه می توانید از دستور type استفاده کنید:
>>> x=2000
>>> type(x)
<type ‘int’>
>>> type(999999999999)
<type ‘long’>
>>> type(1.0)
<type ‘float’>
در مورد تقدم عملگر و عملگر و بسیاری از بحث های تکراری توضیحی داده نمی شود و به مرور با آنها آشنا خواهید شد .
استفاده از سایر انواع پیشرفته پایتون :
خوب تقریبا از این بخش وارد مباحث ویژه پایتون می شویم . پایتون دارای ۳
نوع درونی و پیشرفته تقریبا قابل مقایسه به آرایه و ساختمان C
می باشد . که عبارت است از :
۱.Tuples
۲.Lists
۳.Dictionaries
Tuple یا توالی غیر قابل تغییری از داده همانند آرایه می باشد با این تفاوت
که پس از تعریف و مقدار دهی اولیه قابل هیچ گونه تغییری نمی باشد . علامت
مشخصه آن در هنگام تعریف پارانتز می باشد.
>>> filler = (“string”, “filled”, “by a”, “tuple”)
>>> print “A %s %s %s %s” % filler
A string filled by a tuple
>>> print “The second element of the tuple is ‘%s’” % filter[1] The second element of the tuple is ‘filled’
همانطور که متوجه شدید اندیس همانند C از صفر شروع می شود . برای پیدا کردن طول (تعداد اعضا) یک تیوپل از دستور len استفاده می شود هرگونه تلاش برای تغییر یا دسترسی به اندیس بیشتر از طول تیوپل باعث نمایش خطا می شود:
>>> print “%d” % len(filter)
۳
>>> print a[len(filter) - 1]
tuple
List یا توالی قابل تغییری از داده همانند تیوپل می باشد با این تفاوت که قابلت تغییر و گسترش را دارا می باشد علامت مشخصه آن براکت می باشد .
>>> breakfast = [ “coffee”, “tea”, “toast”, “egg” ]
>>> count = 1
>>> print “Todays breakfast is %s” % breakfast[count]
Todays breakfast is tea
و همانطور که گفتیم لیست امکان تغییر را دارا می باشد .
>>> breakfast[2]="milk"
>>> breakfast
['coffee', 'tea', 'milk', 'egg']
توجه کنید که شما می توانید تنها عناصر موجود را تغییر دهید برای اضافه کردن عناصر و داده های جدید از دستور append استفتده می کنیم .
>>> breakfast.append(“waffle”)
>>> breakfast
['coffee', 'tea', 'milk', 'egg', 'waffle']
اگر قصد دارید تعداد بیشتری از داده ها را در قالب لیست یا تیوپل به لیست موجود اضافه کنید بدین منظور از دستور extend استفاده می کنیم
>>> breakfast.extend([“juice”, “decaf”, “oatmeal”])
>>> breakfast
[‘coffee’, ‘tea’, ‘milk’, ‘egg’, ‘waffle’, ‘juice’, ‘decaf’, ‘oatmeal’]
Dictionary شبیه به لیست و تیوپل می باشد با این تفاوت که ایندکس دیکشنری عددی نمی باشد و می تواند شامل رشته یا در اصطلاح هر اسم دیگری باشد !!
>>> dic={}
>>> dic["name"]="mehdi"
>>> dic["family"]="bayazee"
>>> print dic
{'name': 'mehdi', 'family': 'bayazee'}
نام ایندکس در دیکشنری keys یا کلید و مقدار هر کلید value نامیده می شود . که برای بدست آورد کلیدها و مقادیر می توانید از توابع ()keys و ()values استفاده می شود :
>>> dic.keys()
['name', 'family']
>>> dic.values()
['mehdi', 'bayazee']
نکات
می توانید در پایتون از اندیس دهی معکوس استفاده کنید ! به این صورت که اندیس ۱- آخرین عضو آرایه می باشد .
تکه تکه کردن (Slicing) آرایه و رشته از طریق ترکیب اندیس آغازین و پایانی صورت می گیرد .
>>>last_names = [ “Douglass”, “Jefferson”, “Williams”, “Frank”, “Thomas” ]
>>>last_names[-1]
'Thomas'
>>>last_names[-5]
'Douglass'
>>> s[1:4]
['Jefferson', 'Williams', 'Frank']
>>> s[0][0:6]
'Dougla'
برای مشاهده اعضا هر کلاس (متغییر ها و توابع) می توانید از دستور dir استفاده کنید .
>>> s=[]
>>> dir(s)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__delslice__', '__doc__', '__eq__', '__ge__', '__getattribute__',
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__',
'__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__',
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__',
'__setslice__', '__str__', 'append', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
برای دسترسی با مستندات هر دستور یا کلاس می توانید متغییر __doc__ آن دستور استفاده کنید.
>>> print (s.__doc__)
list() -> new list
list(sequence) -> new list initialized from sequence's items
شرط و حلقه
قبل از اینکه وارد مبحث شرط (if) بشیم یکی از جالبرترین جنبه های پایتون رو توضیح می دم . برخلاف زبانهای دیگری چون C و Pascal که از علایم و عباراتی چون {} و begin,end و … برای نمایش شروع و پایان یک قطعه کد استفده می کنند پایتون دارای علامت یا عبارت خاصی برای این منظور نمی باشد !! و عمل مشخص کردن محدوده یک عبارت که شامل قطعه کد می باشد (مثلا تابع – دستورات شرطی – حلقه – کلاس و … ) از فاصله گزاری استفاده می گردد . به این صورت که پس از خطی که بقیه دستورات زیر مجموعه آن می باشند به اندازه دلخواه فاصله یا تورفتگی داده می شود این فاصله های یکسان تا زمانی ادامه می یابد که محدوده دستور پایان یابد . که این روش باعث کاهش مقدار برنامه و خوانایی برنامه می شود .
دستور شرطی if
شکل کلی if در پایتون به صورت زیر می باشد.
: شرط if
دستورات
مثال : شرط اول به علت اختلاف حرف m مقدار false بوده و هیچ مقداری نمایش داده نمی شود . اما در بخش بعدی با استفاده از تابع عضو کلاس رشته و تبدیل هر دو رشته به حروف کوچک مقدار شرط درست بوده و متن دلخواه چاپ می شود .
>>> if "mehdi" == "Mehdi" :
... print "Same !!"
...
>>> if "mehdi".lower() == "Mehdi".lower() :
... print "Same !!"
...
Same !!
به فاصله داده شده در اول دستور print توجه نمایید . با این توضیح هرگونه فاصله اضافی که باعث ایجاد ابهام گردد تولید خطا می کند . در کد زیر فلش زیر حرف p در دستور print نشان دهنده محل اشتباه منطقی موجود می باشد .
>>> print "Some space !!"
File "<stdin>", line 1
print "Some space !!"
^
SyntaxError: invalid syntax
علامات بکار رفته برای مقایسه دو عبارت و ترکیب عبارات شرطی مطابق علایم زبان C می باشد علایمی چون :
“>” , “<” , “==” , “=!” , “&” , “|” , “=>” , “%” و …
که البته می توانید بجای “&” از and و بجای “| ” از or استفاده کنید .
دستورات تکرار
حلقه while
اولین دستور تکرار یا حلقه while می باشد . به مثال زیر توجه کنید :
>>> omelet={“egg”:۲,“mushroom”:۵,“pepper”:۱,“cheese”:۱, “milk”:۱}
>>> ingredients = omelet.keys()
>>> ingredients
[‘cheese’, ‘pepper’, ‘egg’, ‘milk’, ‘mushroom’]
>>> while len(ingredients) > 0:
... current = ingredients.pop()
... print “Adding %d %s to the mix” % (omelet[current],current)
...
Adding 5 mushroom to the mix
Adding 1 milk to the mix
Adding 2 egg to the mix
Adding 1 pepper to the mix
Adding 1 cheese to the mix
در این مثال ابتدا یک دیکشنری را تعریف می کنیم . (به تعرف یکجا و جدید توجه کنید ) سپس از طریق دستور ()keys کلید (اندیس) های دیکشنری را در متغییر دیگری به نام ingredients می ریزیم . و با وارد کردن نام آن محتویات متغییر را مشاهده می کنیم . (این نوع نمایش فقط در حالت محاوره ای عمل می کند ) سپس با استفاده از دستور while و تا زمانی که تعداد اعضای متغییر ingredients بزرگتر از صفر است وارد حلقه می شویم با دستور ()pop که یک عنصر را از لیست جدا کرده (حذف کرده) و بر می گرداند یکی یکی اعضا لیست ingredients که همان کلید های دیکشنری omelet هستند را در داخل متغییر current ریخته و در سطر بعدی چاپ می کنیم .
حلقه for
دستور بعدی برای حلقه … for … in می باشد . که شبیه به دستور while می باشد با این تفاوت که در این حالت نیازی به تعیین شرط پایان حلقه نبوده و در ضمن متغییری که به تک تک عناصر لیست اشاره می کند ایجاد می گردد که می توانید از آن در داخل حلقه استفاده کنید . معادل مثال بالا را با for به صورت زیر می باشد:
>>> for ingredient in omelet.keys():
... print “adding %d %s to the mix” % (omelet[ingredient],ingredient)
همانطور که مشاهده می کنید کد نوشته شده با for بسیار بهینه تر و
کوتاهتر می باشد . منطق for در پایتون کمی متفاوت می باشد . که شما متغییر (
ingredient ) و یک لیست از عناصر ( ()omelet.keys ) می باشد که با عبارت
کلیدی in از هم جدا شده اند . روند حلقه به این صورت است که متغییر تعریف
شده به تک تک عناصر لیست اشاره خواهد کرد .
همانند زبانهای دیگر حلقه دارای دستوراتی برای جلوگیری از اجرای حلقه بدون
تست شرط و نیز جلوگیری از اجرای بخشی از دستورات و تست دوباره شرط می باشد .
با استفاده از break می توانید بدون تست شرط حلقه را ترک کنید . و دستور
continue از اجرای دستورات جلوگیری کردی مقدار متغییر را تغییر داده و شرط
را بررسی می کند .
استفاده از else در دستورات تکرار :
شاید بهتر بود نام این دستور done یا on_completion بود . چون در آخر حلقه
های تکرار می یاد و زمانی اجرا می شه که حلقه بطور کامل و برای تمامی
مقادیر اجرا شده باشه و دستوری مانند break اجرای عادی حلقه رو ناقص نکرده
باشه .
دو مثال از استفاده else در حلقه for که در اولی به علت اجرای کامل حلقه اجرا نمی شود ولی در مثال دوم اجرا شده است:
>>> for food in (“pate”, “cheese”, “crackers”, “yogurt”):
... if food == “yogurt”:
... break
... else:
... print “There’s no yogurt!”
...
>>> for food in (“pate”, “cheese”, “crackers”):
... if food == “yogurt”:
... break
... else:
... print “There’s no yogurt!”
...
There’s no yogurt!
به تو در تو بودن if و for و رعایت فاصله دقت کنید . توجه کنید که else دقیقا زیر for نوشته شده است پس متعلق به for می باشد نه if !! در حلقه دوم چون yogurt در تیوپل موجود می باشد (تیوپل است چون از پارانتز استفاده شده !) شرط if اجرا می گردد و با دستور break از اجرای ادامه حلقه جلوگیری می شود بنابرین بخش else حلقه به اجرا در می آید.
مدیریت خطاها
شما در درس های گذشته نمونه هایی از پیام های خطای پایتون را مشاهده نمودید . که شامل اطلاعاتی در مورد نوعو نحوه بروز اشکال و خطای موجود می باشد . در مثال بالا اگر سعی کنید به اندیسی دسترسی یابید که تعریف نشده با پیغام خطایی مواجه خواهید شد .
>>> omelet["pate"]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
KeyError: 'pate'
همانطور که مشاهده می کنید نوع خطا KeyError می باشد . شما می توانید با استفاده از دستور … try … except خطاهای بوجود آمده را مدیریت نمایید در این حالت کد های مورد نظر در داخل بخش try نوشته می شود و با استفده از بخش except و تعیین نوع خطای بوجود آمده دستوراتی را که باید هنگام بوجود آمدن این خطا اجرا شوند را بنویسید . مثالی را مطرح کرده و در آن سعی می کنیم به اندیسی دسترسی یابیم که وجود ندارد .
>>> omelet={“egg”:۲,“pepper”:۱,“cheese”:۱, “milk”:۱}
>>> try:
... if omelet[“mushroom”] > 0:
... print “Sure, it have some mushroom”
... except KeyError:
... print “Aww, there’s no mushroom. Lets go shopping !”
...
Aww, there’s no mushroom. Lets go shopping !
دوباره به تورفتگی کدها دقت کنید . شما می توانید مدیریت دلخواه و قدرتمندی بر روی انواع مختلف خطا های موجود داشته باشید .
زمانی که یک خطای زمان اجرا (runtime) اتفاق می افتد حالتی پیش می آید
که اصطلاحا به آن استثنا می گویند . که معمولا برنامه اتمام یافته و پایتون
یک پیام ارور یا خطا چاپ می کند .
برای مثال عمل تقسیم بر صفر یک خطا یا استثنا ایجاد می کند :
>>> print 55/0
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
و یا در حالت های دیگر اگر بخواهید برای مثال به اندیسی از یک آرایه
(لیست , دیکشنری یا تیوپل ) دسترسی داشته باشید که وجود ندارد دوباره یک
استثنا می باشد . در همه حات ها پیام خطا دارای دو بخش می باشد نوع خطا که
قبل از دو نقطه می آید و توضیحی در مورد خطا که بعد از دو نقطه ظاهر می
گردد . معمولا پایتون در بخشی به نام Traceback محل وقوع خطا را نیز مشخص
می کند .
معمولا ما قصد داریم تعداد این خطا ها به حداقل برسد . ولی چون به صفر
رساندن آنها غیر ممکن می باشد باید تمحیداتی را برای مدیریت این خطاها و
جلوگیری از خاتمه برنامه باندیشیم . در پایتون می شه این مدیریت بر خطاها و
استثناها را از طریق try و except انجام داد .
برای مثال فرض کند شما نام یک فایل را از کاربر می گیرید و قصد دارید آنرا
باز کنید اگر مشکلی در انجام این فرایند پیش بیاید برای مثال اگر فایل
موجود نباشد نمی خواهیم برنامه قفل کند یا ناخواسته خاتمه یابد بلکه ما می
خواهیم این خطاها مدیریت شده و کاربر از خطای اتفاق افتاده آگاه شده و
تصمیمی درست در جهت رفع آن بیندیشد یا حتی خود برنامه تصمیم گیری کند .
به مثال زیر توجه کنید در این مثال نام یک فایل پرسیده شده و با استفاده از try و except سعی بر باز کردن آن می گردد :
filename = raw_input('Enter a File name : ')
try :
fp = file(filename, "r")
except :
print 'There is no file named ', filename
وقتی پایتون به این قطعه کد می رسد ابتدا کد های بخش try را اجرا می کند
در صورتی که هیچ خطا و استثنایی اتفاق نیفتد بخش except را نادیده گرفته و
کد های بعد آنرا اجرا می کند . اما در صورتی که خطایی اتفاق بیفتد ادامه
اجرا قطع شده و بخش except اجرا می گردد .
شما می توانید از چنیدن بخش except برای مدیریت خطاهای مختلف استفاده کنید .
در درون برنامه خود نیز اگر متوجه اشکالی شدید می توانید یک حالت استثنا
را ایجاد کنید تا در بخش دیگر بتوانید آنرا مدیریت نمائید . در زیر مثالی
را مشاهده می کنید .
def GetAge():
age = input ("Enter your age : ")
if age < 18 :
raise 'BadNumberError' , 'Your age must be greader than 18 !!'
return age
همانطور که مشاهده می کنید این تابع یک عدد را از کاربر دریافت می کند و
اگر مقدار آن کمتر از ۱۸ باشد یک استثنا ایجاد می کند و در حالت عادی
اجرای برنامه را متوقف می کند . دستور raise دو متغییر می گیرد اولی نوع
استثنا و دومی اطلاعاتی در مورد خطای اتفاق افتاده نوع استثنای
BadNumberError یک نوع جدید از استثنا هست که ما از آن در این تابع استفاده
کرده ایم .
در هنگام استفاده از try و except می توانید اطلاعات ارسالی از تابع raise را دریافت و چاپ کنید :
>>> s=[]
>>> try:
... print s[1]
... except IndexError,er:
... print "We have an error : ",er
...
We have an error : list index out of range
در مثال زیر نیز نحوه مدیریت جدا و همزمان چندین خطا را مشاهده می کنید .
s = [5,6,0,2]
x = input("Enter an Index : ")
try:
print "%.2f" %(10.0/s[x])
except IndexError :
print "Sorry , we have not this index !!"
except ZeroDivisionError :
print "The value of this index is zero ! i can not devide it .."
نمونه ای از خروجی
Enter an Index : 2
The value of this index is zero ! i can not devide it ..
Enter an Index : 10
Sorry , we have not this index !!
Enter an Index : 1
۱.۶۷
قراردادن برنامه در فایل
با افزایش حجم برنامه تایپ آن به صورت محاوره ای مشکل خواهد شد و با بروز هر مشکلی کل آن باید دوباره نوشته شود . در ثانی ما اکثر اوقات می خواهیم از برنامه ای که نوشته ایم بعدا استفاده کنیم . پس باید بتوانیم متن برنامه خود را در جایی ذخیره کنیم که بعدا بتوانیم به آن دسترسی داشته باشیم . که در این حالت از فایل اسکریپت استفاده می کنیم که قبلا نیز توضیح داده شده است . میتوانید این فایل را بصورت مستقیم اجرا نمایید . روش دیگری برای اجرا وجود دارد و آن استفاده از مفسر پایتون با پارامتر i می باشد . در این حالت متن فایل اجرا شده و سپس وارد حالت محاوره ای می شود و شما امکان ادامه برنامه اجرا شده و استفاده از توابع م متغییر های درون فایل را در حالت محاوره ای خواهید داشت .
توابع
منطق توابع در پایتون شبیه به دیگر زبانهای برنامه نویسی می باشد . برای تعریف یک تابع از کلمه کلیدی def استفاده می کنیم و سپس نام تابع را نوشته و نام پارامتر ها را در داخل پارانتز وارد می کنیم و با قرار دادن دو نقطه روی هم شروع به تایپ متن تابع می کنیم . در صورتی که اولین سطر بعدی یک رشته یاشد این رشته به عنوان توضیحات کنار گذاشته می شود و شما می توانید با متغییر __doc__ عضو کلاس تابع آن را مشاهده کنید .
def in_fridge ():
“””This is a function to see if the fridge has a food.
fridge has to be a dictionary defined outside of the function.
the food to be searched for is in the string wanted_food”””
try:
count = fridge[wanted_food]
except KeyError:
count = 0
return count
دیدن مستندات تابع
>>> print “%s” % in_fridge.__doc__
This is a function to see if the fridge has a food.
fridge has to be a dictionary defined outside of the function.
the food to be searched for is in the string wanted_food
مشاهده سایر متغییر ها و توابع عضو کلاس
>>> dir(in_fridge)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
'__get__', '__getattribute__', '__hash__', '__init__', '__module__',
'__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults',
'func_dict', 'func_doc', 'func_globals', 'func_name']
متغییر ها و توابعی که با کاراکتر ‘ __ ‘ شروع شده اند خصوصی (private ) می باشند که نوضیحات بیشتر در مورد آنها را در بخش کلاس ها خواهیم آموخت .به هریک از این متغییر ها یا توابع می توان با روشی همانند دسترسی به متغییر __doc__ دسترسی داشت.
استفاده از اسامی یکسان در جاهای مختلف
همانطور که در تابع تعریف شده بالا مشاهده می کنید دیکشنری fridge و رشته wanted_food در داخل تابع تعریف نشده اند و از نتغییر های هم اسمی که در خارج محدوده تابع تعریف شده اند استفاده می کنند . پایتون متن برنامه را به محدوده ای مجزایی به نام scope تقسیم می کند . اسامی و scope که در همه نواحی و در کل برنامه قابل دسترسی می باشد با نام global یا سراسری شناخته می شود . همه اسامی دیگر در داخل توابع در یک سطح پایین تر به نام ناحیه local یا محلی قرار دارند . توابع این ناحیه را با توابعی که در سطح یکسان هستند به اشتراک نمی گزارند . و هر کدام یک ناحیه کاری مجزا دارند . هر نامی در ناحیه بالاتر قابل استفاده در ناحیه پایین تر می باشد با این توضیح که این استفاده فقط مقداری می باشد (نه مرجعی ) یعنی دستورات ناحیه کاری پایین تر نمی توانند تغییری در آنها اعمال کنند و فقط به یک کپی از آنها دسترسی دارند . به مثال زیر توجه کنید .
>>> special_sauce = [‘ketchup’, ‘mayonnaise’, ‘french dressing’]
>>> def make_new_sauce():
... “””This function makes a new special sauce all its own”””
... special_sauce = [“mustard”, “yogurt”]
... return special_sauce
...
یک لیست با نام special_sauce در ناحیه کاری بالا (top level) ایجاد گردیده است . و تابعی تعریف می شود که ناحیه کاری آن زیر مجموعه ناحیه کاریی می باشد که متغییر مورد نظر در آن تعریف شده است . پس می توان از درون تابع make_new_sauce به یک کپی از متغییر special_sauce دسترسی داشت . در داخل این تابع متغییری هم اسم با متغییر تعریف شده در سطح بالاتر (global) را تعریف می کنیم و مقداری متفاوت با آنچه قبلا تعریف شده را به آن می دهیم . و آن را با دستور return بر می گردانیم . زمانی که این دستورات اجرا شوند شما مشاهده خواهید کرد که مقدار متغییر تعریف شده در ناحیه سراسری بدون تفییر می ماند.
>>> print “%s” % special_sauce
[‘ketchup’, ‘mayonnaise’, ‘french dressing’]
>>> new_sauce = make_new_sauce()
>>> print special_sauce
[‘ketchup’, ‘mayonnaise’, ‘french dressing’]
>>> print new_sauce
[‘mustard’, ‘yogurt’]
ابتدا مقدار متغییر special_sauce چاپ کرده و سپس یک متغییر جدید و با استفده از تابع تعریف شده ایجاد می کنیم سپس دوباره محتویات متغییر اصلی را نمایش می دهیم (بدون تغییر می باشد ) و در نهایت متغییر جدید را چاپ می کنیم . بخاطر داشته باشید می توانند از اسامی یکسان ولی متفاوت درون خود استفاده کنند .
ارسال متغییر به تابع
در مثال بالا ما از متغییر های سراسری استفاده کردیم . که این روش همیشه مناسب نمی باشد . ما می توانیم متغییر های خود را به تابع ارسال کنیم . مثال بالا را طوری تغییر می دهیم که متغییر ها را به عنوان پارامتر گرفته و نتیجه را برگرداند .
def in_fridge(some_fridge, desired_item):
try:
count = some_fridge[desired_item]
except KeyError:
count = 0
return count
این تابع را در فایلی با نام func1.py ذخیره کرده و با دستور python -i func1.py اجرا کرده و وارد حالت محاوره ای شوید .
>>> fridge = {‘apples’:۱۰, ‘oranges’:۳, ‘milk’:۲}
>>> wanted_food = “oranges”
>>> in_fridge(fridge, wanted_food)
۳
مقدار دهی پیش فرض پارامتر ها
در هنگام فراخوانی تابع باید به هر پارامتر آن یه مقدار نسبت داد (فرستاد). و در صورتی که مقداری به یک پارامتر فرستاده نشود باعث بروز خطای برنامه نویسی خواهد شد . برای جلوگیری از این حالت پایتون شما را قادر می سازد تا برای پارمترها تابع خود مقدار پیش فرض نسبت دهید . این کار را می توانید در هنگام تعریف تابع و با نسبت دادن مقدار پیش فرض بوسیله علامت تساوی به نام پارامتر انجام دهید .
def make_omelet2(omelet_type = “cheese”):
حال شما می توانید این تابع را با ورودی یا بدون ورودی فراخوانی کنید .
تابع در داخل تابع
شما می توانید تابعی را درون تابع تعریف کنید . زمانی که می خواهید تابعی بزگتر و پیچیده را به بخش هایی کوچکتر تقسیم کنید می توانید هر یک از این بخش ها را به عنوان یک تابع درون تابع اصلی تعریف کنید . که در این حالت نحوه تعریف همانند تعریف تابع معمولی می باشد . با این تفاوت که از بیرون تابع اصلی نمی توان به توابع عضو دسترسی داشت .
تست پارامتر ها
چون متغییر ها در پایتون دارای نوع ثابت نیستند و عولا می توان در بازه های زمانی مختلف انواع متفاوتی از یک متغییر را داشت پس امکان ارسال انواع داده های مختلف به توابع هم هست که ممکن است باعث بروز خطا گرددند یا نتایج اشتباهی را تولید کنند . برای جلوگیری از اینگونه موارد باید نوع متغییر خود را قبل از استفاده در داخل تابع تست کنیم .
def make_omelet(omelet_type):
if type(omelet_type) == type({}):
print “omelet_type is a dictionary with ingredients”
return make_food(omelet_type, “omelet”)
elif type(omelet_type) == type(“”):
omelet_ingredients = get_omelet_ingredients(omelet_type)
return make_food(omelet_ingredients, omelet_type)
else:
print “I don’t think I can make this : %s” % omelet_type
در این مثال ابتدا نوع متغییر omelet_type بررسی می شود اگر نوع آن دیکشنری باشد نشان دهنده مواد لازم برای تهیه غذا می باشد پس تابع make_food با این دیکشنری و غذایی با نام omelet که به همراه آن ارسال شده فراخوانی و سپس نتیجه زر طریق دستور return برگشت داده می شود . در قسمت بعدی (elif معدل else if می باشد ) اگر متغییر ارسالی از نوع رشته باشد فرض بر این خواهد بود که نام نوع خاصی از املت می باشد پس ابتدا از طریق تابع get_omelet_ingredients مواد لازم برای پختن آن را بدست آورده و این مواد را همراه با نام آن به تابعی که کار درست کردن غذا را انجام میدهد ارسال می کنیم . در بقیه موارد پیامی را چاپ می کنیم مبنی بر اینکه نمی توانیم غذای خواسته شده را درست کنیم !!
کلاس ها و اشیا
مبحث مهم بعدی در برنامه نویسی پایتون بحث کلاس و اشیا می باشد . من
توضیح مختصری در مورد برنامه نویسی شی گرا ارائه می کنم در صورتی که آشنایی
با مبحث کلاس و اشیا و برنامه نویسی شی گرا ندارید پیشنهاد می کنم از
منابع موجود برنامه نویسی شی گرا استفاده کنید . ولی توضیحات ارائه شده در
اینجا نیز تا حدودی شما را با این سبک برنامه نویسی و روشها و ویژگی های آن
آشنا خواهد ساخت .
تا کنون با انواع داده های مختلف آشنا شدید و توابعی را نیز نوشته و به کار
بردید . همه این توابع و متغییر ها مستقل بوده و بطور مجزا مورد استفاده
قرار می گرفتند . این روش که به برنامه نویسی ساخت یافته یا مبتنی بر روال و
توابع جدا می باشد کلیت برنامه را به روالها و اجزا کوچکتر تقسیم می کند و
باعث آسانتر شدن اشکال زدایی و استفاده مجدد از کد های نوشته شده می شود
اما برنامه هایی موسوم به اسپاگتی کد را تولید می کند یعنی برنامه هایی که
کد ها همانند ضرف حاوی ماکارونی بهم ریخته و درهم بود و سروته برنامه مشخص
نمی باشد . گام بعدی در برنامه نویسی که یک الهام از طبیعت ( OOP (Object
Oriented Programming یا همان برنامه نویسی شی گرا است این سبک برنامه
نویسی یک برنامه را همانند طبیعت به اشیا سطح بالا تقسیم می کند و هر شی
قسمتی از مساله ای را که به دنبال حل آن هستید مدل سازی می کند در این حالت
اشیا با یکدیگر در حال تعامل می باشند به نحوی که اجزا و اشیا برنامه همه
باهم روند برنامه را پیش می برند . در این صورت ، یک برنامه شی گرا به صورت
مدل و شبیه سازی زنده از مساله ای خواهد بود که در صدد حل آن هستید . رکن
اساسی برنامه نویسی شی گرا کلاس می باشد که در واقع یک طرح کلی از یک
موجودیت مجزا می باشد و اشیا با توجه به آن ایجاد می گردند . یک کلاس شامل
متغییر و توابع می باشد و این دو رکن اساسی برنامه در یک موجودیت واحد به
نام کلاس جمع شده است . در مثال های قبل شما با این مبحث آشنا شده و حتی از
آن استفاده کردید . برای مثال وقتی یک رشته تعریف می کنید این رشته همانند
زبانی چون C فقط شامل کاراکتر ها نمی باشد بلکه یک شی از کلاس رشته می
باشد و متغییر های عضوی چون مقدار رشته نسبت داده شده و توابع یا اصطلاحا
متد هایی را داراست . برای مثال وقتی شما رشته ای را بر قرار دادن یک نقطه
بعد از آن و نوشتن عبارتی چون ()upper آن را به حروف بزرگتر تبدیل می کنید
در واقع از تابی عضو کلاس و شی رشته استفاده کرده اید . شما اطلاعی از نحوه
کار و نوع رابطه این تابع با دیگر تابع ها و متغییر های داخل کلاس رشته
ندارید ولی نحوه استفاده از آن را می دانید که این موضوع یکی از جنبه های
مثبت برنامه نویسی شی گرا است . متد ها یا توابع در این سبک برنامه نویسی
به عنوان یک رفتار و عمل برای کلاسی خاص می باشند که شما کافی است طریقه
استفاده از آن را بدانید ! همانطور که قبلا هم گفته شد شما می توانید با
دستور dir عناصر (هم متغییر و هم تابع) عضو یک کلاس را مشاهده کنید.
name="Tux-World.Com"
dir(name)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__','__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
__getslice__','__gt__', '__hash__', '__init__', '__le__', '__len__',
'__lt__', '__mod__','__mul__', '__ne__', '__new__', '__reduce__',
__reduce_ex__', '__repr__','__rmod__', '__rmul__', '__setattr__',
'__str__', 'capitalize', 'center', 'count','decode', 'encode',
'endswith', 'expandtabs', 'find', 'index', 'isalnum','isalpha',
'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join',
'ljust','lower', 'lstrip', 'replace', 'rfind', 'rindex', rjust',
'rsplit', 'rstrip','split', 'splitlines', 'startswith', 'strip',
'swapcase', 'title', 'translate','upper', 'zfill']
متغییر ها و توابعی که به ‘ __ ‘ شروع شده اند عناصر خصوصی یا private کلاس می باشند یعنی شما مجاز به استفاده از آنها نیستید اما می توانید ایتفاده کنید ! در واقع پایتون مانع استفاده شما از این عناصر نمی شود و این بستگی به انتخاب شما دارد . در مثال زیر ابتدا نوع عنصر __len__ از کلاس رشته را بررسی می کنیم . چون نوع آن تابع می باشد آن را اجرا می کنیم . عدد برگشت داده شده همان طول متغییر است . تابع len هم از همین متغییر هر کلاس استفاده می کند به همین دلیل است که می تواند طول داده های پیچیده را نیز مشخص کند .
>>> type (name.__len__)
<type 'method-wrapper'>
>>> name.__len__()
۱۳
ادامه درس را با بیان مثالی کلی و کامل کردن آن ادامه می دهیم . فرض کنید می خواهید از یک یخچال در برنامه خود استفاده کنید ! شبیه سازی یک یخچال درست مثل حالت واقعی آن ، بسیار مفید و کارا خواهد بود و این همان کاری هست که برنامه نویسی شی گرا انجام می دهد . فرض کنید می خواهید اعمالی چون اضافه کردن غذا ، برداشتن آن ، اطلاع از موجود بودن غذا یا میوه ای خاص و یا قرار دادن یا برداشتن بیش از یک چیز در یک زمان خاص را انجام دهید . به عبارت دیگر وقتی شما برنامه ای می نویسید که در آن از اشیا دنیای واقعی استفاده می کنید شبیه سازی عینی آن بصورت یک عنصر واحد به حل مسئله و تسهیل برنامه نویسی کمک شایانی خواهد کرد.
تعریف کلاس
تعریف کلاسزمانی که شما قصد ایجاد یک کلاس و نوشتن کد ها و بخش های
مختلف آن را دارید کافی است فقط از عبارت کلاس باضافه نام کلاس استفاده
کنید و همانند سایر قطعه های کد آن را با دو نقطه پایان دهید . و سپس شروع
به نوشتن کد کنید . در مرحله بعدی می توانید یک نمونه از این کلاس (شی) را
ایجاد . اسم خاصی را به آن نصبت دهید سپس از طریق این اسم می توانید به
عناصر (متغییر و متد) داخل آن شی (کلاس) دسترسی داشته باشید .
در مثال زیر ساده ترین کلاس ممکنه را می بینید که فقط شامل توضیحات می باشد .
Class Fridge:
"""This class implements a fridge where ingredients can be added and removed individually, or in groups."""
توضیح اینکه هر متنی پس از تعریف کلاس نوشته شود به عنوان مستندات آن کلاس بوده و تاثیری بر اجرای آن ندارد و می توانید به این مستندات از طریق متفییر __doc__ آن کلاس دسترسی داشته باشد .
ایجاد یک شی از کلاس تعریف شده
کد کلاس Fridge را در یک فایل نوشته و آن را بوسیله دستور python -i اجرا کنید . شما اکنون می توانید یک نمونه از کلاس تعریف شده را به همراه اسم آن و پارانتز بازو بسته ایجاد کنید :
>>> f = Fridge()
فعلا این کلاس و درنتیجه ای شی خالی می باشد . البته به این معنی نیست که بی کاربرد است . شما الان هم می توانید آن را تغییر دهید !! در ثانی استفاده از کلاس ها در مبحث استثنا ها کاربرد دارد که در درسهای آینده مفصل بحث خواهد شد . و اما استفاده از شی خالی f و مشاهده مستندات آن :
>>> f.items = {}
>>> f.items["milk"] = 2
>>> f.items["milk"]
۲
>>> f.__doc__
'This class implements a fridge where ingredients can be added and removed individually, or in groups.'
اکنون باید به طراحی کلاس یخچال بپردازید به این منظور باید هدف خود از
این کار و نیز کاربرد دقیق کلاس خود را مشخص کنید در اولین گام باید
بتوانیم عناصری را در یخچال قرار دهیم . روشهای متعددی موجود است افزودن یک
عدد از یک شی و یا چندین موجودیت با تعداد مختلفو به وسیله نوع داده
دیکشنری .
در مرحله بعدی شما باید بتوانید اشیایی را از آن بردارید و نیاز دارید
همانند موقع قرار دادن اشیا یک عدد از یک عنصر با بصورت گروهی این کار را
انجام دهید .
اعمال و خواسته (تابع یا متد) های دیگری نیز مورد نیاز است تا این یخچال
کامل شود . به متد هایی که شی را در دسترس قرار می دهد و بوسیله انها با شی
تعامل می کنید رابط نام دارند . چون نحوه ارتباط درون کلاس و شی را با
محیط بیرون مشخص می کنند . مثال خود را کاملتر می کنیم :
class Fridge:
"""This class implements a fridge where ingredients can be added and
re moved individually, or in groups. The fridge will retain a count
of every ingredient added or removed, and will raise an error if a
sufficient quan tity of an ingredient isn't present.
Methods:
has(food_name[, quantity])-checks if the string food_name is in the fridge.
Quantity will be set to 1 if you don't specify a number.
has_various(foods)-checks if enough of every food in the dictionary is in the fridge
add_one(food_name) - adds a single food_name to the fridge
add_many(food_dict) - adds a whole dictionary filled with food
get_one(food_name) - takes out a single food_name from the fridge
get_many(food_dict) - takes out a whole dictionary worth of food.
get_ingredients(food) - If passed an object that has the __ingredients__
method, get_many will invoke this to get the list of ingredients.
"""
def __init__(self, items={}):
“””Optionally pass in an initial dictionary of items”””
if type(items) != type({}):
raise TypeError,”Fridge requires a dictionary not %s”% type(items)
self.items = items
return
همانطور که مشاهده می کنید برای توابع نیز توضیحاتی نوشته ایم . که انجام این عمل توصیه می گردد .
تابه __init__ همان تابع سازنده می باشد این تابع هنگام تعریف کلاس فعال
شده و کارهایی را که در داخل آن تعریف شده انجام می دهد . این تابع دو
پارامتر دارد . اولی self می باشد که معادل this در دیگر زباهای برنامه
نویسی می باشد و به خود شی اشاره می کند و از آن می توان به عناصر داخل
کلاس دسترسی داشت . به عبارت دیگر در داخل هر تابعی که خواستید به یکی از
عناصر خود کلاس دسترسی یابید باید این متغییر را به عنوان پارامتر ارسال
کنید و مثل تابع بالا از آن به همراه جدا کننده نقطه برای دسترسی به عناصر
عضو همین شی استفاده کنید . در صورتی که در زبانهای شی گرای دیگری چون ++C
این کار نیاز نیست . پس در پایتون شما می توانید در داخل یک تابع ، توابع و
متغییرهایی هم اسم با متغییر ها و متد های عضو همان کلاس تعریف و استفاده
کنید بدون اینکه تداخلی باهم داشته باشند . که در مثال بالا مشهود است و دو
نوع متغییر با نام items موجود است یکی به عنوان ورودی و دیگری عضو کلاس .
هنگام نوشتن توابع عضو و متد های یک کلاس باید بیشترین دقت را داشته باشید
برای مثال نوشتن توابعی چون برداشتن یک شی از یخچال ، برداشتن دو شی از
یخچال و برداشتن چند شی از یخچال باعث تکرار کد های تکراری ، بالا رفتن حجم
برنامه و پایین آمدون کارایی و مشکل شدن استفاده از آن خواهد بود و به
عبارت کلی تر بهینه نخواهد بود . پس می توان برای مثال قسمت مشترک این متد
ها را در یک متد خصوصی و درونی پیاده شازی کرده و در بقیه فقط از آن
استفاده کرد . پس بهتر است در مثال ذکر شده یک تابع درونی با نام
add_multi__ نوشته شود که دو پارامتر (یکی اسم شی و دیگری تعداد آن) را
دریافت کرده و آنها را به محتویات یخچال اضافه کند . در ادامه مثال ذکر شده
را کاملتر خواهد شد ولی از تکرار کد های قبلی اجتناب می شود فقط چون
تورفتگی در پایتون مهم است تعریف کلاس را که در اینجا مبنای سایر کد ها می
باشد ذکر می کنیم .
class Fridge:
# the docstring and intervening portions of the class would be here, and
# __add_multi should go afterwards.
def __add_multi(self, food_name, quantity):
"""
__add_multi(food_name, quantity) - adds more than one of a
food item. Returns the number of items added
This should only be used internally, after the type checking has been
done
"""
if not self.items.has_key(food_name):
self.items[food_name] = 0
self.items[food_name] = self.items[food_name] + quantity
خوب اکنون موقع نوشتن دو تابع دیگر یعنی افزودن یک عدد از یک شی و چندین مقدار مختلف است که هر دو از تابع پایه و درونی تهریف شده بالا ( add_multi__ ) استفاده خواهند کرد .
def add_one(self, food_name):
"""
add_one(food_name) - adds a single food_name to the fridge returns True
Raises a TypeError if food_name is not a string.
"""
if type(food_name) != type(""):
raise TypeError,"add_one requires a string, not %s" %type(food_name)
else:
self.__add_multi(food_name, 1)
return True
def add_many(self, food_dict):
"""
add_many(food_dict) - adds a whole dictionary filled with food as keys and
quantities as values.
returns a dictionary with the removed food.
raises a TypeError if food_dict is not a dictionary
returns False if there is not enough food in the fridge.
"""
if type(food_dict) != type({}):
raise TypeError,"add_many requires a dictionary, not %s" % food_dict
for item in food_dict.keys():
self.__add_multi(item, food_dict[item])
return
اضافه کردن یک عنصر بسیار شبیه به تابع دوم می باشد . و در هر دو از یک کد مشترک و تابع درونی add_multi__ استفاده شده است . اگر از تابع add_one استفاده شود ابتدا نوع آن بررسی می شود تا حتما رشته باشد ( چون نوع های دیگر هم می توانند فرستاده شوند ) سپس تابع درونی add_multi__ را با همان متغییر به همراه عدد یک فراخوانی و در نتیجه شی در یخچال قرار می گیرد . در حالت دوم یعنی امکان اضافه کردن چندین مقدار همزمان ابتدا نوع آن تست می شود در صورتی که دیکشنری نبود پیغام خطایی نمایش داده می شود و در غیر اینصورت با یک حلقه به کلید های آن دسترسی یافته و سپس همان کلید را با مقدار آن را به تابع add_multi__ ارسال می کنیم . همانگونه که مشاهده می کنید از طریق دستور raise که جزو توابع مدیریت استثناها و خطاهای برنامه نویسی می باشد یک پیام انتخابی به همراه نوع خاصی از ارور (یعنی TypeError) نمایش داده شده و برنامه خاتمه می یابد . چند مثال :
>>> f = Fridge({"eggs":6, "milk":4, "cheese":3})
>>> f.items
{'cheese': 3, 'eggs': 6, 'milk': 4}
>>> f.add_one("grape")
True
>>> f.items
{'cheese': 3, 'eggs': 6, 'grape': 1, 'milk': 4}
>>> f.add_many({"mushroom":5, "tomato":3})
>>> f.items
{'tomato': 3, 'cheese': 3, 'grape': 1, 'mushroom': 5, 'eggs': 6, 'milk': 4}