کتاب عصر پایتون/فصل دوم: متغیر‌ها و کار با آن‌ها

ویکی‎کتاب، کتابخانهٔ آزاد
پرش به ناوبری پرش به جستجو
Gnome-go-last.svg Gnome-go-first.svg

متغیر‌ها و کار با آن‌ها[ویرایش]

مقادیر و انواع داده[ویرایش]

مقدار یا داده یکی از تعاریف پایه‌ای و بنیادی است و همانند عدد یا حرف تعاریف وسیع و متعددی دارد. متغیرها را به‌صورت «ظرف» تصور کنید تا در خطایابی مشکلی نداشته باشید. هر برنامۀ کامپیوتری در روند اجرای خود با مجموعه‌ای از داده‌ها و اطلاعات سروکار دارد؛ آن‌ها را مورد پردازش قرار داده، و نتایجی را تولید می‌کند. یک مقدار در علم برنامه‌نویسی می‌تواند برای مثال عددی چون “۱” یا مقداری رشته‌ای مانند “سلام دنیا!” باشد.

دو نوع دادۀ ذکر شده در بالا انواع گوناگونی دارند. یکی از آن‌ها از نوع عدد صحیح یا integer و دیگری رشته یا در اصطلاح برنامه‌نویسی string است. اگر شما قادر به تشخیص نوع یک داده نیستید مفسر پایتون می‌تواند این کار را برای شما انجام دهد.

>>> type("Hello, World!")
<type string>
>>> type(17)
<type int>

علاوه‌بر موارد اعداد صحیح و رشته، اکثر زبان‌های برنامه‌نویسی دارای انواع دیگری چون اعداد حقیقی، اعداد بزرگ، کاراکتر و ... می‌باشند.

متغیرها[ویرایش]

یکی از مهم‌ترین مزیت‌های یک زبان برنامه‌نویسی، توانایی کار کردن با متغیرها است. متغیر نامی است که به یک مقدار نسبت داده می‌شود. در اکثر زبان‌ها برای استفاده از متغیرها باید ابتدا آن‌ها را تعریف یا ایجاد کنید. و نیز معمولاً هنگام تعریف هر متغیر نوع آن را که تا آخر عمر متغیر ثابت خواهد ماند، باید مشخص کنید. در زبان پایتون برای تعریف یک متغیر کافی است آن را مقداردهی کنید. یعنی نیازی به تعریف جداگانه نیست. نکتۀ بعدی این است که در زبان پایتون ابزار مدیریتی داینامیک و بسیار قوی برای متغیر پیاده‌سازی شده است. این ابزار امکانات بسیاری را فراهم می‌کند. برای مثال نوع متغیر در پایتون می‌تواند در طول عمر آن متغیر یا در طول اجرای برنامه به تعداد دلخواه تغییر یابد.

>>> message = "Be Linux !"
>>> n = 17
>>> pi = 3.14159

در مثال بالا ۳ متغیر را با عمل مقداردهی تعریف کرده‌ایم. اکنون برای مشاهدۀ مقدار هر متغیر می‌توانید از دستور print استفاده کنید. این دستور مقدار هر متغیر را در خروجی چاپ می‌کند.

>>> print message
Be Linux !
>>> print pi
3.14159

متغیر نامی است که به یک مقدار نسبت داده می‌شود

در پایتون نوع داده در زمان اجرا مشخص می‌شود و نیازی به اعلان آن قبل از اجرا نیست. همچنین تمامی داده‌ها شیء (object) هستند. برای مثال عدد ۳ در پایتون یک شیء را در حافظه مشخص می‌کند. متغیرها نیز نام‌هایی هستند که به اشیاءِ داخل حافظه اشاره می‌کنند. شاید این سؤال پیش بیاید که چگونه مفسر پایتون می‌تواند نوع داده‌ها را بدون اعلان اولیه تشخیص دهد؟

پاسخ:

name1='saeed afshari'
name2='saeed afshari'

وقتی در پایتون انتساب‌هایی به‌صورت بالا انجام می‌شود، مراحل زیر به ترتیب اجرا خواهد شد:

۱. شیء saeed afshari که مقداری از نوع رشته است به وجود می‌آید.

۲. متغیرهای name1, name2 ساخته می‌شوند. (اگر قبلاً ساخته نشده باشند)

۳. متغیرهای name1, name2 به اشیاء مورد نظر اشاره می‌کنند.

شیء موردنظر باید نوع خود را بداند، برای همین منظور هر object در پایتون دارای دو فیلد سرآمد (header field) به نام‌های طراح نوع (type designator) و شمارندۀ مراجعات (reference counter) است که طراح نوع، نوع داده را در خود ذخیره می‌کند و شمارندۀ مراجعات تعداد رجوع‌های متغیرهای متفاوت به شیء را مشخص می‌کند.

برای مثال بالا type designator = str و reference counter = 2 است ** با داشتن این فیلدها در زمان اجرا مفسر می‌تواند نوع داده را تشخیص دهد.

مدیریت حافظۀ خودکار[ویرایش]

reference counter کار زباله‌روبی (garbage collection) را بسیار آسان می‌کند. به این صورت که وقتی reference counter مساوی صفر می‌شود زباله‌روب متوجه می‌شود که هیچ ارجاعی به شیء مورد نظر وجود ندارد، بنابراین شیء را از حافظه پاک می‌کند.

نام‌گذاری متغیرها[ویرایش]

معمولاً برنامه‌نویسان برای نام‌گذاری متغیرها از نام‌هایی استفاده می‌کنند که نشان‌دهندۀ کاربرد و حتی نوع متغیر باشد. اسامی متغیرها می‌توانند نام‌هایی با طول دلخواه باشند. در نام‌گذاری متغیرها استفاده از حرف و عدد مجاز است. به‌یاد داشته باشید که در برخی از زبان‌ها از جمله پایتون حروف برزگ با کوچک یکسان نیستند. بنابراین متغیری با نام Joker با متغیر joker یکسان نیست و این دو ممکن است مقادیر و حتی نوع‌های متفاوتی داشته باشند. در نام‌گذاری متغیرها می‌توان از کاراکتر زیر خط (_) نیز استفاده کرد و معمولاً در نام‌هایی که از بیش از یک واژه تشکیل شده باشند به کار می‌رود.

همچون تمام زبان‌های برنامه‌نویسی پایتون هم قوانینی برای نام‌گذاری متغیرها دارد که باید هنگام نام‌گذاری به آنها دقت کنید. برخی از این قوانین از این قرار است:

اسم متغیر باید با یک حرف شروع شود .

در نام‌گذاری مجاز به استفاده از کاراکترهای خاص چون $ % ^ # / و ... نیستید.

در نام‌گذاری متغیرها نباید از اسامی رزرو شدۀ زبان برنامه‌نویسی استفاده کرد. برای مثال استفاده از نام‌هایی چون class , for , if و ... مجاز نیست. همان‌طور که گفته شد استفاده از اسامی رزور شده در پایتون مجاز نیست. در صورت استفاده از این اسامی یا عدم رعایت هر یک از موارد بالا برنامه از روند عادی خود خارج شده و متوقف می‌شود. و در اصطلاح یک خطای نحوی (syntax error - مربوط به نحوۀ نوشتن و یا املای دستورات برنامه) رخ می‌دهد.

به‌یاد داشته باشید که ممکن است اسمی که برای یک متغیر انتخاب می‌کنید تکراری نیز باشد. در این حالت شما خطایی دریافت نمی‌کنید اما برنامه نتایجی اشتباه محاسبه خواهد کرد یا روند اجرای آن به مشکل برخواهد خورد.

اسامی رزرو شده در پایتون[ویرایش]

زبان پایتون ۲۸ اسم رزرو شده دارد. این اسامی یا keywordها تشکیل‌دهندۀ ساختار کلی هر زبان برنامه‌نویسی هستند.

raise   not     import   for    else    continue    and  
return  	or  	  in	   from	except	def 	assert
try 	pass	is  	global  	exec	del 	break
while	print	lambda  	  if	  finally 	elif	class

عبارات[ویرایش]

یک عبارت در حقیقت یک دستور برنامه‌نویسی است که مفسر پایتون قادر به اجرای آن باشد. تاکنون و در این درس شما با دو نوع عبارت آشنا شده‌اید. یکی دستور چاپ و دیگری مقداردهی. در زبان پایتون معمولاً هر عبارت در یک سطر مجزا نوشته می‌شود و مفسر پس از اجرای هر سطر یا عبارت سراغ سطر بعدی می‌رود.

یک برنامه یا اسکریپت شامل تعدادی از عبارت‌ها یا دستورات اجرایی پشت سر هم می‌باشد.

عبارات محاسباتی[ویرایش]

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

>>> 1 + 1
2

عملگر و عملوند[ویرایش]

عملگر در حقیقت یک سمبل یا نماد قراردادی برای نمایش اتفاق افتادن عملی خاص مانند جمع یا تفریق است. به این ترتیب هر عملگر بر روی تعدادی عملوند عمل کرده و نتیجه‌ای را حاصل می‌دهد.

اولویت عملگرها[ویرایش]

زمانی که یک عبارت محاسباتی شامل چندین عملگر باشد ترتیب اجرای عملگرها مهم بوده و در نتیجۀ کلی عبارت تأثیرگذار است. بنابراین برای به‌دست آوردن نتیجه‌ای یکسان و استاندارد از قوانینی برای ترتیب اجرای عملگرها استفاده می‌شود. قوانین اولویت عملگر در پایتون دقیقاً با قوانین عملگرهای ریاضی یکسان است.

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

به جز توان، عملگرهایی که اولویت یکسانی دارند به ترتیب و از سمت چپ به راست اجرا می‌گردند.

>>> 3 ** 2 ** 2
81

در مثال فوق ابتدا عدد ۳ به توان ۲ رسیده و نتیجه یعنی ۹ محاسبه می‌شود. سپس عدد پایه و اصلی ۹ به توان ۲ می‌رسد. دقت کنید که این قانون نیز برگرفته از ریاضیات است.

تقدم عملگرها در زبان پایتون[ویرایش]

ردیف عبارات توضیحات

۱	() [] .	گروهبندی و دسترسی
۲	! - +	عملگرهای یکتایی
۳	**	توان
۴	* / %	ضرب ، تقسیم ، باقیمانده
۵	+ -	جمع و تفریق
۶	<< >>	عملگرهای شیفت به چپ و راست باینری
۷	< =< > =>	عملگرهای مقایسهای : بزرگتر ، کوچکتر و ...
۸	== =!	عملگرهای مقایسه : مساوی ، نابرابر
۹	&	و منطقی باینری
۱۰	^	یا انحصاری (XOR) باینری
۱۱	|	یا منطقی باینری
۱۲	and	و منطقی
۱۳	or	یا منطقی
۱۴	= =+ =- =* =/ =%	عملگرهای مقداردهی

عملگرهای رشته[ویرایش]

در حالت عادی و منطقی شما قادر به اعمال عملگرهای محاسباتی روی رشته‌ها نیستید. برای مثال دستورات زیر همگی اشتباه بوده و اجرای آن‌ها باعث بروز خطای منطقی خواهد شد.

>>> "Hello" / 123
>>> "15" + 2
>>> ""Hello" * "World !"

نمونۀ خروجی

>>> "15" + 2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot concatenate 'str' and 'int' objects

خروجی در پایتون ۳٫۰

>>> "15" + 2
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
    "15" + 2
TypeError: Can't convert 'int' object to str implicitly

اما برخی از عملگرها دارای معانی خاصی در مورد رشته می‌باشند.

اتصال دو رشته با استفاده از عملگر جمع[ویرایش]

عملگر ترکیب دو رشته که با سمبل مربوط به عمل جمع ریاضی یا “+” نشان داده می‌شود دو عملوند از نوع رشته را دریافت و رشتۀ سمت راست خود را به انتهای رشته سمت چپی خود می‌چسباند.

>>> fname = "Mehdi "
>>> lname = "Bayazee"
>>> fname + lname
'Mehdi Bayazee'

تکرار یک رشته با استفاده از عملگر ضرب[ویرایش]

عملگر ضرب با نماد * نیز معنی خاصی برای رشته دارد. این عملگر دو عملوند یکی از نوع رشته و دیگری از نوع عدد صحیح را دریافت و رشته را به تعداد عدد دریافت شده تکرار کرده و در قالب یک رشتۀ واحد بر می‌گرداند.

>>> "Python ! " * 3
'Python ! Python ! Python ! '

عملگر ضرب در مورد رشته‌ها منطقی شبیه به نوع ریاضی آن دارد. ضرب دو عدد در ریاضیات را می‌توان به‌صورت جمع نشان داد. برای مثال ۴×۳ را می‌توان بصورت ۴+۴+۴ نمایش داد. در مورد رشته‌ها نیز در حقیقت برای محاسبه ضرب یک عدد در رشته، همان رشته به تعداد عدد وارد شده با هم جمع می‌شود.

کامنت یا توضیحات در پایتون[ویرایش]

با زیاد شدن حجم برنامه و کدهای نوشته شده، خواندن و درک هر سطر از کد کاری سخت و زمان‌بر می‌شود. معمولاً خواندن بخشی از کد یک برنامه و درک کامل آن در زمانی کم کار مشکلی است. به همین دلیل معمولاً برنامه‌نویسان در هنگام نوشتن برنامه توضیحاتی را به کد برنامه اضافه می‌کنند که نشان‌دهندۀ وظیفۀ بخشی از کد است و قابلیت اجرایی ندارد. این توضیحات در اصطلاح برنامه‌نویسی comment نام دارد. هر زبانی برای جدا کردن کامنت‌ها از کد اصلی معمولاً از کاراکتر یا کاراکترهای خاصی استفاده می‌کند. کاراکتر مربوط به این کار در پایتون علامت # است. بعد از این علامت و تا آخر سطر هر متنی که نوشته شود، هنگام اجرا توسط مفسر نادیده گرفته می‌شود.

کار با بیت‌ها[ویرایش]

شاید وجود این مبحث در پایتون (که یکی از آسان‌ترین زبان‌های برنامه‌نویسی است) کمی به نظر عجیب باشد؛ ولی گاهی لازم است که با بیت‌ها کار کنیم. از این رو در اکثر زبان‌های برنامه‌نویسی عملگرهایی برای کار با بیت تعبیه شده‌اند.

همان‌طور که می‌دانید بیت (Bit) کوچکترین واحد برای ذخیره‌سازی داده ها است. کار با بیت‌ها می‌تواند دلایل مختلفی ازجمله انجام عملیات محاسباتی، کار کردن و ارتباط داشتن با سخت‌افزارها به صورت مستقیم، رمزنگاری و ... داشته باشد. یکی دیگر از موارد مهم استفاده، صرفه‌جویی در حافظۀ برنامه‌های بزرگ است. البته برای کار با بیت‌ها باید با محاسبات باینری (جبر بولی) آشنا باشید.

عملگرهای بیتی (bit operator):[ویرایش]

عملگرهای بیتی را می‌توان به چند دسته تقسیم کرد:

۱. عمگر انتقال (shift)؛

۲. عملگر منطقی (همانند درست و غلط)؛

۳. عملگر متمم (یا معکوس).

۱. عملگرهای انتقال[ویرایش]

این عملگر برای انتقال بیت‌ها به سمت راست یا چپ استفاده می‌شود. به عنوان مثال عدد 50 به‌صورت باینری به این صورت نمایش داده می‌شود (00110010) اگر بخواهیم این عدد را دو بیت به سمت راست منتقل کنیم (تقسیم بر 4) به عدد 12 تبدیل می‌شود (00001100).

>>> 50 >> 2
12
>>>

پرونده:Bit operator 01.gif

همان‌طور که مشاهده می‌کنید چون قرار است دو بیت به سمت راست انتقال دهیم دو بیت آخر حذف می‌شود و طبق قاعده باید دو بیت (با ارزش صفر) به سمت راست اضافه کنیم تا 8 بیت کامل باشد. حال می‌خواهیم همین عدد 50 را دو بیت به سمت چپ منتقل کنیم (ضرب‌در 4).

>>> 50 << 2
200
>>>

پرونده:Bit operator 02.gif

وقتی عدد 50 را دو بیت به سمت چپ انتقال دهیم به عدد 200 تبدیل می‌شود. همان‌طور که در مثال‌ها مشاهده کردید رابطه‌ای میان انتقال به چپ یا راست و تعداد بیت‌ها وجود دارد.

پرونده:Bit operator 01.gif

پس از این عملگرهای انتقال می‌توان برای انجام اعمال محاسباتی (ضرب و تقسیم) اعداد صحیح استفاده کرد. (باید متوجه شده باشید که همان‌طور که در شکل نشان داده شده است، قسمت اعشاری در جواب‌ها از بین می‌رود. و باید مراقب باشید که سرریز (overflow) رخ ندهد.) عملگرهای بیتی را می‌توان فقط برای اعداد صحیح (int , long) به‌کار برد.

۲. عملگرهای منطقی:[ویرایش]

عملگرهای منطقی برای مقایسه دو بیت از یک عدد صحیح مورد استفاده قرار می‌گیرد.

  • & (and):

بیت نتیجه 1 است اگر و فقط اگر دو بیت 1 باشند در غیر این صورت بیت نتیجه 0 است.

  • (or):

اگر حداقل یکی از بیت‌ها 1 باشد بیت نتیجه 1 است در غیر این صورت بیت نتیجه 0 است.

  • ^ (xor):

اگر دو بیت ارزش مخالف داشته باشند (مثلا یکی 0 و دیگری 1 باشد) بیت نتیجه 1 خواهد بود در غیر این صورت بیت نتیجه 0 است.

این عملگرها برای دو عدد صحیح به‌کار می‌روند و دو بیت متناظر هر یک را با هم مقایسه می‌کنند. به مثال زیر توجه کنید:

>>> 50 & 20
16
>>> 50 | 20
54
>>> 50 ^ 20
38
>>>

پرونده:Bit operator 01.gif

۳. عملگر متمم (معکوس):[ویرایش]

این عملگر (~) روی ارزش تمام بیت‌های تشکیل‌دهنده تأثیر می‌گذارد و تمام آن‌ها را معکوس می‌کند. یعنی هر 0 به 1 و هر 1 به 0 تبدیل می‌شود به عنوان مثال اگر عدد 15 (00001111) را معکوس کنیم به عدد 240 (11110000) تبدیل می‌شود.

در پایان باز هم به این نکته اشاره می‌کنم که عملگرهای بیتی تنها روی داده‌هایی از نوع (long , int) کار می‌کنند.