GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||
GeezerVison is showing pythonpersian.com — درس ۰۶: سینتکس زبان پایتون — کتاب پایتون به پارسی
"نه مرگ آنقدر ترسناک است و نه زندگی آنقدر شیرین که انسان برای این دو شرفش را بدهد" نامتان جاوید باد درس ۰۶: سینتکس زبان پایتون¶
در این درس به معرفی اجزای پایه در زبان برنامهنویسی پایتون پرداخته شده و اینکه چه هستند، چه گرامری دارند، چه کاری انجام میدهند یا... مورد بررسی قرار گرفته است. همچنین در موارد بسیاری نکتههایی از شیوه استاندارد پایتوننویسی که توسط سند PEP 8 به برنامهنویسان پایتون پیشنهاد میشود نیز آورده شده است؛ رعایت این اصول به یکدستی کدهای جامعه پایتون کمک میکند. [1] سینتکس (Syntax) مجموعهای از قواعد است که چگونگی برنامهنویسی به یک زبان مشخص را تعریف میکند؛ برای نمونه اینکه یک متن چطور نوشته شود که توسط مفسر پایتون به عنوان توضیح در نظر گرفته شود یا یک شی رشته، به رعایت سینتکس تعریف شده در پایتون بستگی دارد و چنانچه مفسر نتواند متن را با هیچ قاعده تعریف شدهای مطابقت دهد یک استثنا گزارش خواهد شد. سینتکس پایتون تنها محدود به این درس نیست و موارد بسیار دیگری به مانند چگونگی تعریف اشیا گوناگون را در طی درسهای آتی مشاهده خواهید کرد. ✔ سطح: مقدماتی سطرها¶مفسر پایتون و همچنین کاربر، کدهای درون هر ماژول را در قالب تعدادی سطر میبینند؛ سطرهای فیزیکی (Physical Lines) و منطقی (Logical Lines). سطرهای فیزیکی در واقع همان سطرهایی است که توسط ویرایشگرهای متن شمارهگذاری میشوند و به راحتی توسط کاربر قابل تشخیص هستند ولی سطرهای منطقی برداشت مفسر از اجزای برنامه است؛ هر سطر منطقی بیانگر یک دستور (Statement) پایتون است. برای نمونه دستور انتساب (Assign): 1msg = "Hello World!" 2print(msg) در نمونه کد بالا: سطر یکم، یک دستور انتساب (Assign) را نشان میدهد؛ این دستور مقدار سمت راست خودش را به متغیر هر چند که پیشنهاد میشود همیشه هر سطر فیزیکی تنها شامل یک سطر منطقی باشد ولی یک سطر فیزیکی را میتوان شامل چند سطر منطقی نیز در نظر گرفت: 1msg = "Hello World!"; print(msg) در این حالت میبایست سطرهای منطقی (یا همان دستورها)، توسط کاراکتر گاهی نیز بهتر است برای خوانایی بیشتر، یک سطر منطقی را در قالب چند سطر فیزیکی پیادهسازی نماییم: 1msg = "Python Programming \ 2Language." # This is a message. 3print(msg) در نمونه کد بالا: دو سطر فیزیکی نخست از دید مفسر به شکل تنها یک سطر منطقی دیده میشود. در پایتون برای شکستن یک دستور در چند سطر فیزیکی از کاراکتر نکته [PEP 8]: طول هر سطر فیزیکی نباید از ۷۹ کاراکتر بیشتر شود. برای متنهای طولانی نیز مانند توضیح (Comment) و Docstring طول هر سطر فیزیکی باید حداکثر ۷۲ کاراکتر در نظر گرفته شود. برای خوانایی بیشتر بهتر است دستورهای طولانی شکسته شوند. دستورهایی که شامل 1month_names = ['Januari', 'Februari', 'Maart', # These are the 2 'April', 'Mei', 'Juni', # Dutch names 3 'Juli', 'Augustus', 'September', # for the months 4 'Oktober', 'November', 'December'] # of the year که در این حالت برخلاف استفاده از «سطرهای خالی» (Blank lines): سطری که تنها حاوی فضای خالی (Spaceها یا Tabها) باشد، توسط مفسر نادیده گرفته میشود و به بایتکد ترجمه نمیگردد. از این سطرها میتوان برای خوانایی بیشتر کدها بهره گرفت - مانند سطر سوم در نمونه کد پایین: 1def power(a, b): 2 return a ** b 3 4print power(2, 3) مستندسازی¶هر چند اساس طراحی زبان پایتون بر خوانایی بالای کد است ولی «مستندسازی» (Documentation) برنامه یعنی استفاده از امکاناتی همچون ارایه توضیح در کدها میتواند به درک و خوانایی هر چه بهتر کدهای برنامه برای مراجعات آینده برنامهنویس و افراد دیگری که میخواهند بر روی توسعه آن فعال باشند یا از آن استفاده کنند نیز بسیار مفید خواهد بود. در این بخش به بررسی دو امکان درج Comment و Docstring برای مستندسازی برنامه میپردازیم. توضیح¶یک «توضیح» (Comment) در زبان پایتون توسط کاراکتر هدف از نوشتن توضیح در میان کدها، شرح منطق یک تکه کد است و اینکه کد مورد نظر چرا نوشته شده و چه کاری انجام میدهد. گاهی نیز از ویژگی توضیح (اینکه توسط مفسر نادیده گرفته میشود) برای غیرفعال کردن کدها بهره گرفته میشود. توضیح نقش زیادی در خوانایی کدها دارد و استفاده مرتب از آن پیشنهاد میشود. توضیح در پایتون تنها به شکل تک سطری تعریف شده است و برای درج توضیحهایی با بیش از یک سطر فیزیکی باید توجه داشت که هر سطر به صورت جداگانه میبایست با نکته [PEP 8]: متن توضیح با یک فضای خالی (Space) بعد از 1# This is a comment, it helps you to understand the code later on. 2# Anything that comes after the # symbol is ignored by Python. 3 4print("I could have code like this.") # This comment explains that the following comment will be ignored. 5 6# You can also use a comment to temporarily "disable" or comment out a piece of code: 7# print ("This won't run.") 8 9print("This will run.") Docstring¶در کنار «توضیح»؛ ”Docstring“ نیز امکان دیگری در پایتون برای ارایه توضیح بیشتر درباره کدهای برنامه است. متن Docstring توسط سه علامت نقل قول ( 1def complex(real=0.0, imag=0.0): 2 """Form a complex number. 3 4 Keyword arguments: 5 real -- the real part (default 0.0) 6 imag -- the imaginary part (default 0.0) 7 """ >>> complex.__doc__ 'Form a complex number.\n\n Keyword arguments:\n real -- the real part (default 0.0)\n imag -- the imaginary part (default 0.0)\n ' >>> print(complex.__doc__) Form a complex number. Keyword arguments: real -- the real part (default 0.0) imag -- the imaginary part (default 0.0) >>> ملاحظه
مخاطب متن «توضیح» موجود در کد، کاربرانی میباشند که آن کد را توسعه میدهند در حالی که مخاطب اصلی Docstringها کاربرانی است که از کد مربوط به آن استفاده میکنند بنابراین Docstring باید به توضیح چگونگی استفاده از کد (به صورت خاص: ماژول، تابع، کلاس و متد) بپردازد. Docstring باید به عنوان دستور نخست درج گردد و این نکته برای یک ماژول در صورت وجود سطر اجرای مفسر به صورت پایین در نظر گرفته میشود: #!/usr/bin/env python """ Module docstring. """ import [...] [...] بستهها (Packages) نیز میتوانند Docstring داشته باشند؛ برای این منظور Docstring باید درون ماژول نکته Docstringها در هر جای دیگری از کدهای برنامه نیز به عنوان جایگزینی برای توضیحهای چند سطری قابل استفاده هستند که در این حالت مفسر آنها نادیده گرفته و دیگر قابل دستیابی نیستند. تورفتگی¶بلاکبندی در زبان پایتون توسط «تورفتگی» (Indentation) سطرها مشخص میگردد؛ این عمل در زبانهایی مانند C و Java توسط آکولاد // C if (x > y) { x = 1; y = 2; } # Python if x > y: x = 1 y = 2 در تصویر پایین به شیوه تورفتگی بلاکها نسبت به سرآیند خود توجه نمایید:
نکته [PEP 8]: در ایجاد تورفتگی استفاده از کلید Space نسبت به کلید Tab ترجیح داده میشود - برای هر مرتبه تورفتگی از چهار کلید Space استفاده نمایید. روش رایج ایجاد تورفتگی استفاده از کلید Space است و سعی کنید هرگز به صورت ترکیبی از کلیدهای Sapce و Tab استفاده نکنید چرا که از نسخه 3 پایتون امکان استفاده ترکیبی از این دو کلید وجود ندارد! اگر مایل به استفاده از کلید Tab هستید باید به صورت یکدست تمام تورفتگیهای برنامه خود را فقط با استفاده از آن ایجاد نمایید. اجباری به تورفتگی آن بخشی از دستورها که به سطرهای فیزیکی دیگر شکسته شدهاند وجود ندارد اما بهتر است برای خوانایی بالاتر، این بخشها را با کمی تورفتگی بیشتر نسبت به دستورهای بدنه بلاک جاری نوشته شوند: 1def long_function_name( 2 var_one, var_two, var_three, 3 var_four): 4 print(var_one) در دستورهایی به مانند پایین نیز ایجاد تراز آرگومانها هم حالت مناسبی است: 1foo = long_function_name(var_one, var_two, 2 var_three, var_four) دستور¶«دستور» (Statement) واحدی از کد است که شامل کلمههای کلیدی بوده، اجرا میگردد و کاری را به انجام میرساند. در پایتون دو نوع دستور وجود دارد: دستورهای ساده (Simple Statements): دستورهایی هستند که تنها در یک سطر منطقی پیادهسازی میشوند. مانند دستور دستورهای مرکب (Compound Statements): گروهی از دستورها هستند که میتوانند یک بخشی (مانند: دستور 1def binary_search(seq, key): 2 lo = 0 3 hi = len(seq) - 1 4 while hi >= lo: 5 mid = lo + (hi - lo) // 2 6 if seq[mid] < key: 7 lo = mid + 1 8 elif seq[mid] > key: 9 hi = mid - 1 10 else: 11 return mid 12 return False شناسه¶«شناسه» (Identifier) نامی است نمادین که به دلخواه کاربر تعیین و از آن برای شناسایی (identify) متغیرها، توابع، کلاسها، ماژولها یا دیگر اشیا پایتون از یکدیگر استفاده میشود. انتخاب شناسه در پایتون نکاتی دارد که میبایست از سوی کاربر در نظر گرفته شود:
با یک نگاه حرفهایتر، ساختار لغوی (Lexical) شناسه به شکل پایین بیان میشود [اسناد پایتون]: identifier ::= (letter|"_") (letter | digit | "_")* letter ::= lowercase | uppercase lowercase ::= "a"..."z" uppercase ::= "A"..."Z" digit ::= "0"..."9" ملاحظه در تعاریف regex: از پرانتز نکته
برای نمونه - چند شناسه درست: a _p __var MyClass get_length getLength var2 var_2 S01E16 برای نمونه - چند شناسه نادرست: me@mail get.length 2_var 6 $var 4pi نکته همانطور که از درس یکم میدانیم، پایتون یک زبان حساس به حرف (Case Sensitive) است و مفسر آن بین حروف کوچک (Lowercase) و بزرگ (Uppercase) به مانند a و A تمایز میگذارد. برای نمونه، تمامی شناسههای CaR ،cAR ،CAr ،caR ،cAr ،Car ،car و CAR متفاوت با یکدیگر ارزیابی میشوند. در پایتون از تکنیکی به نام Name Mangling استفاده میشود. توسط این تکنیک و تنها با شیوه انتخاب شناسهها، نقشی خاص به آنها داده میشود:
جدا از این مورد، در پایتون صفتها (Attributes) و متدهای خاصی وجود دارد که از پیش تعریف گشتهاند و برای مفسر مفهوم مشخصی دارند. شناسه این صفتها و متدها با دو کاراکتر بنابراین به هنگام استفاده از کاراکتر نکته [PEP 8]: شیوه استاندارد انتخاب شناسه برای کلاس، تابع، متد و متغیر به صورت پایین است:
برای شناسههای تک حرفی توجه داشته باشید که از انتخاب حروف l (اِل کوچک) و I (آی بزرگ) بهتر است اجتناب کنید زیرا این دو حرف در برخی فونتها شبیه هم هستند و البته همینطور حرف O (اُ بزرگ) که میتواند شبیه به صفر باشد. کلمههای کلیدی¶نکته پایانی در مورد شناسهها این است که: نمیتوان یک شناسه را برابر با یکی از «کلمههای کلیدی» (keywords) پایتون انتخاب کرد. کلمههای کلیدی در واقع شناسههایی هستند که از پیش برای مفسر پایتون تعریف شدهاند و معنای مشخصی برای آن دارند. فهرست این کلمههای در پایتون به صورت پایین است: >>> help("keywords") Here is a list of the Python keywords. Enter any keyword to get more help. False class from or None continue global pass True def if raise and del import return as elif in try assert else is while async except lambda with await finally nonlocal yield break for not در کتابخانه استاندارد پایتون ماژولی به نام >>> import keyword >>> keyword.iskeyword(a) False >>> keyword.iskeyword("def") True >>> keyword.kwlist ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield'] ملاحظه تابع شاید کنجکاو باشید تعداد کلمههای کلیدی پایتون را بدانید؛ برای این منظور نیازی به شمارش دستی نیست!: >>> import keyword >>> len(keyword.kwlist) 33 ملاحظه تابع نکته تنها کلمههای کلیدی نکته [PEP 8]: چنانچه میخواهید شناسهای مشابه با یکی از کلمههای کلیدی انتخاب نمایید؛ میتوانید این کار را با استفاده از یک متغیر¶یک «متغیر» (Variable) در بیشتر زبانهای برنامهنویسی به مانند C بیانگر محلی در حافظه میباشد که مقداری در آن قرار گرفته است. برای نمونه سه دستور پایین را در نظر بگیرید: int a = 1; a = 2; int b = a; در نمونه کد بالا: دستور
ولی در پایتون: یک متغیر چیزی نیست جز یک نام که به یک شی مشخص در حافظه ارجاع (یا اشاره) دارد. تعریف متغیر در پایتون بسیار ساده است و تنها با انتساب (Assign) شی به یک نام ایجاد میگردد. نمادِ a = 1 a = 2 b = a مفسر با رسیدن به دستور
انتساب شی دیگری (که میتواند از هر نوع دیگری باشد) به یک متغیر موجود؛ باعث حذف ارجاع قبلی آن و ارجاع به شی جدید میشود. دستور ولی اکنون که ارجاعی به شی هر شی شامل یک «شمارنده ارجاع» (Reference Counter) نیز هست؛ به این صورت که در هر لحظه تعداد ارجاعها به آن شی را نشان میدهد و با هر ارجاع جدید به شی، یک واحد به آن اضافه میشود و با حذف هر ارجاع نیز یک واحد کاهش مییابد. چنانچه مقدار آن به صفر برسد، شی آن توسط تکنیک ”Garbage Collection“ پاک میگردد و مقدار حافظهای که توسط شی مصرف شده بود آزاد میگردد. برای مشاهده تعداد ارجاعها به یک شی میتوان از تابع البته مفسر پایتون اعداد صحیح و رشتههای کوچک را پس از اینکه مقدار شمارنده ارجاع آنها به صفر برسد از حافظه پاک نمیکند. هدف از این کار صرفه جویی در هزینه ایجاد این اشیا برای استفاده در آینده است. بنابراین در پاسخ به سوال بالا باید گفت که: شی >>> import sys >>> a = 1 >>> sys.getrefcount(1) 760 >>> a = 2 >>> sys.getrefcount(1) 759 >>> sys.getrefcount(2) 96 >>> b = a >>> sys.getrefcount(2) 97 در نمونه کد بالا همانطور که مشاهده مینمایید تعداد ارجاعها به شی انتساب چندگانه¶امکان ایجاد همزمان چند متغیر یا انتسابهای چندگانه در پایتون وجود دارد - بنابراین میتوان چند متغیر که همگی به یک شی ارجاع دارند را تنها با یک دستور ایجاد کرد: >>> a = b = c = "python" >>> a 'python' >>> b 'python' >>> c 'python' برای انتساب اشیا متفاوت میبایست از ویرگول (Comma) و تنها یک عملگر انتساب ( >>> a, b, c, d = 1, 4.5, "python", 2 >>> a 1 >>> b 4.5 >>> c 'python' >>> d 2 یکی از کاربردهای انتساب چندگانه این است که میتوان اشیا دو متغیر را به سادگی و تنها با یک سطر دستور با یکدیگر عوض کرد: >>> a = 1 >>> b = 2 >>> a, b = b, a >>> a 2 >>> b 1 ثابت¶«ثابت» (Constant) به متغیری گفته میشود که مقدار آن همواره ثابت بوده و پس از تعریف دیگر امکان تغییر مقدار آن وجود ندارد. برای نمونه یک ثابت در زبان Java به شکل پایین تعریف میگردد - پس از دستور پایین هر گونه تلاش برای تغییر مقدار ثابت 1final int HOURS = 24; در پایتون امکانی برای تعریف ثابت پیشبینی نشده است!. علاوه بر امکان ایجاد ثابتها برخی موارد دیگر نیز در پایتون نادیده گرفته شده است. در واقع فرض پایتون بر این است که کاربران او افراد باهوشی هستند که از پس مشکلات برمیآیند؛ در نتیجه میگوید: من به کاربرانم اعتماد دارم پس نیازی نیست که تمام کارها را من برای آنها انجام دهم، یک برنامهنویس باید بتواند ریسک کند!. ولی برای ایجاد ثابت میتوانید متغیرهای مورد نظر خود را در ماژولی جدا تعریف نمایید و در هر جایی که لازم بود با 1# File: constant.py 2# Path: /home/user/Documents/MyModule 3 4HOURS = 24 >>> import sys >>> sys.path.append('/home/user/Documents/MyModule') >>> import constant >>> constant.HOURS 24 البته اگر تغییرناپذیر بودن متغیرها برایتان اهمیت ویژه دارد میتوانید ماژولی حاوی کد پایین ایجاد نمایید [منبع]: 1# File: constant.py 2# Path: /home/user/Documents/MyModule 3 4class _const: 5 6 class ConstError(TypeError): pass 7 8 def __setattr__(self, name, value): 9 if name in self.__dict__: 10 raise self.ConstError("Can't rebind const(%s)" % name) 11 self.__dict__[name] = value 12 13import sys 14sys.modules[__name__] = _const() >>> import sys >>> sys.path.append('/home/user/Documents/MyModule') >>> import constant >>> constant.HOURS = 24 >>> constant.HOURS 24 >>> constant.HOURS = 23 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/user/Documents/MyModule/constant.py", line 10, in __setattr__ raise self.ConstError("Can't rebind const(%s)" % name) constant.ConstError: Can't rebind const(HOURS) >>> constant.HOURS 24 درک کد کلاس
نکته [PEP 8]: برای نامگذاری ثابتها (Constants) تنها از حروف بزرگ و برای جداسازی کلمهها نیز از NoneType¶[None] یک شی آماده و بدون مقدار در پایتون است: >>> n = None >>> type(n) <class 'NoneType'> >>> print(n) None >>> import sys >>> sys.getsizeof(a) 16 >>> n = 5 >>> type(n) <class 'int'> این شی را میتوان معرف مقدار هیچی یا این شی کاربردهای فراوانی دارد که به مرور با آنها آشنا خواهید شد. عملگرها¶«عملگر» (Operator) به نمادی گفته میشود که عمل مشخصی را بر روی اشیا به انجام میرساند؛ به مانند عملگر انتساب عملگرهای حسابی (Arithmetic Operators)¶
عملگرهای مقایسه (Comparison Operators)¶
عملگرهای انتساب (Assignment Operators)¶
عملگرهای بیتی (Bitwise Operators)¶
این دسته از عملگرها، عمل مشخصی را بر روی تک تک بیتهای عملوند(ها) انجام میدهند. در پایتون برای استفاده از این عملگرها لزومی به تبدیل اعداد به پایه دو (دودویی یا باینری Binary) وجود ندارد ولی در اینجا برای مشاهده بهتر عملکرد آنها از اعداد دودویی استفاده کردهایم. در زبان پایتون اعداد پایه دو همواره میبایست با یک >>> a = 0b0011 >>> a 3 >>> b = 0b0010 >>> b 2 از تابع >>> bin(10) '0b1010' >>> type(bin(10)) <class 'str'> >>> 0b1010 10
عملگرهای منطقی (Logical Operators)¶این عملگرها عبارتند از
عملگر عملگرهای عضویت (Membership Operators)¶شامل دو عملگر
>>> "py" in "python" True >>> 1 in [1, 2, 3] True >>> "s" not in "python" True >>> 3 not in [1, 2, 3] False عملگرهای هویت (Identity Operators)¶شامل دو عملگر
>>> a = 3 >>> a is 3 True عملگر شیرماهی (Walrus Operator)¶از نسخه 3.8 پایتون یک عملگر جدید به نام Assignment Expressions یا Walrus Operator به سینتکس پایتون اضافه شده است. [PEP 572]. نمایش این عملگر به شکل >>> walrus = False >>> print(walrus) False >>> print(walrus := True) # Python >= 3.8 True >>> walrus True دو نمونه کد بالا عملکرد یکسانی دارند با این تفاوت که در نمونه دوم تنها با استفاده یک سطر کد، متغیر ترتیب اجرای عملگرها (Operator Precedence)¶چنانچه عبارتی شامل چندین عملگر باشد؛ اینکه ابتدا عمل کدامیک بررسی شود، در حاصل نتیجه تاثیرگذار خواهد بود. هر کدام از عملگرها از دید مفسر پایتون دارای حق تقدم متفاوتی است (مانند دیگر زبانهای برنامهنویسی). بنابراین همواره هنگام درج یک عبارت، میبایست به میزان تقدم آنها نیز توجه کرد. در بخش پایین به بررسی اولویت عملگرها خواهیم پرداخت - اولویت از بالا به پایین کاهش میابد: 1( ) # پرانتز 2** 3~ 4- + # منفی و مثبت 5* / // % 6- + # بعلاوه و منها 7<< >> 8& ^ | 9== != <> 10< <= > >= 11= **= /= //= %= *= -= += 12is is not 13in in not 14not and or پرانتز بالاترین اولویت را دارد به این معنی که هر عبارتی داخل آن قرار بگیرد اولویت بیشتری برای بررسی خواهد داشت؛ در پرانتزهای تودرتو نیز اولویت داخلیترین پرانتز از همه بیشتر است. چنانچه عبارتی شامل چند عملگر هم سطح باشد؛ اولویت عملگر سمت چپتر بیشتر است. به عبارتهای پایین و حاصل آنها توجه نمایید: >>> 4 + 2 - 3 + 2 * 5 13 >>> 4 + ((2 - 3) + 2) * 5 9 >>> 9 / 3 * 2 6.0 >>> 3 * 2 / 9 0.6666666666666666 >>> (5 - 3) ** (7 - 3) 16 >>> 4 + 3 ** 2 - 9 / 3 * 3 4.0 >>> 4 * 2 == 5 + 3 True پینوشت¶😊 امیدوارم مفید بوده باشه | ||||||||||||||||||||||||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |