قواعد زبان پایتون

[بندانگشتی|قوانین رعایت شده در هنگام [برنامه‌نویسی رایانه‌ای|برنامه‌نویسی]]
مجموعهٔ قوانین زبان برنامه‌نویسی پایتون مجموعهٔ قوانین هستند که می‌توان برنامه‌هایی قابل فهم برای ماشین به این زبان نوشت. در طراحی این زبان به شدت سعی شده‌است که به سادگی قابل فهم باشد؛ این به این مفهوم است که سعی شده‌است که مجموعهٔ دستورها آن به نگارش دستورها در زبان انسان نزدیک باشد.

## فلسفه طراحی
پایتون زبانی قابل فهم و بسیار خواندنی است. این یک طرح بصری نسبتاً نامشخص است و از کلمات کلیدی انگلیسی استفاده می‌کند که اغلب در سایر زبان‌ها از حروف نگارشی استفاده می‌کنند. پایتون قصد دارد ساده و سازگار با طراحی نحو آن باشد، به گونه‌ای که در مانترا محصور شده و «برای انجام آن باید یک روش — و ترجیحاً فقط یک راه
— وجود داشته باشد» از طریق ذن پایتون.

این مانترا عمداً مخالف مانترا پرل و روبی است، «در این زبان‌ها، بیش از یک راه برای انجام آن وجود دارد».

## واژه‌های کلیدی
واژه‌های کلیدی واژه‌هایی هستند که ساختار قواعد این زبان را مشخص می‌کنند؛ لذا نمی‌توان از آن‌ها به عنوان نام متغیرها استفاده کرد.

*`and`
*`as`
*`assert`
*`async`
*`await`
*`break`
*`class`
*`continue`
*`def`
*`del`
*`elif`
*`else`
*`except`
*`False`
*`finally`
*`for`
*`from`
*`global`
*`if`
*`import`
*`in`
*`is`
*`lambda`
*`None`
*`nonlocal`
*`not`
*`or`
*`pass`
*`raise`
*`return`
*`True`
*`try`
*`while`
*`with`
*`yield`

; یادداشت‌ها


## دندانه دار نوشتن
برای مشخص کردن بلوک‌های برنامه، پایتون از فضاهای خالی و **دندانه دار نوشتن**  استفاده می‌کند. به‌طور معمول در بسیاری از زبان‌های مشهور مانند C و Java از ساختار آکولاد برای مشخص کردن بلوک‌های برنامه استفاده می‌شود:

```c
void foo(int x)
{
    if (x == 0) {
        bar();
        baz();
    } else {
        qux(x);
        foo(x - 1);
    }
}
```

در صورتی که برنامهٔ معادل فوق در پایتون به صورت زیر است:

```python
def foo(x):
    if x == 0:
        bar()
        baz()
    else:
        qux(x)
        foo(x - 1)
```

مشاهده می‌کنید که چگونه فاصلهٔ اضافی (معمولا یک tab) مشخص‌کنندهٔ بلوک‌های برنامه است. اگرچه استفاده از هردو فاصله و tab در نسخه‌های کنونی پایتون معمول است، استفاده هم‌زمان از هردو آن‌ها موجب سردرگمی و ایجاد اشتباهات ناآگاهانه می‌شود؛ لذا معمولاً تنها از tab یا تنها از فاصله استفاده می‌شود.

## نوع داده‌ها
در پایتون، نوع داده‌ها به صورت دینامیک از روی مقداری که به متغیرها نسبت داده می‌شود تعیین می‌شود. در واقع هیج نوعی برای مغیری که مقداردهی نشده‌است، تعریف نمی‌شود. بلکه نوع متغیر مورد نظر توسط مقدار نسبت داده شده تعیین می‌شود. نوع داده‌ها در پایتون دارای اطلاعات ارجاع به نوع شیئی هستند که از آن ساخته شده‌اند. این ویژگی‌ها در جایگاه‌های مختلف در رفتار پایتون تأثیر می‌گذارد.
به خاطر ویژگی دینامیک بود نوع داده‌ها در پایتون، تبدیل نوع متغیرها احتیاج به در قالب ریختن متغیرها  ندارد. به عنوان یک عدد موهومی در یک عدد صحیح بلند را ضرب کنید و پایتون به صورت خودکار نوع حاصل را تعیین می‌کند. اگرچه همیشه این امکان‌پذیر نیست! به عنوان مثال ضرب یک رشته در یک عدد معنی ندارد!

### نوع‌های پایه
پایتون انواع پایه مختلفی را پشتیبانی می‌کند. به عنوان مثال اعداد صحیح، حقیقی  محاسبات با دقت دلخواه و اعداد موهومی.
به‌طور کلی نوع داده‌ها در پایتون به دو دستهٔ تغییرناپذیر  و تغییرپذیر  تقسیم می‌شوند. به عنوان مثال رشته‌ها در پایتون تغییرناپذیر هستند. تغییرناپذیر متغیرها در پایتون به این معنی است که نمی‌توان متغیر را بعد از ایجاد دستکاری کرد؛ لذا برای بر خلاف بسیاری از زبان‌های دیگر، تغییر رشته در باعث ایجاد رشته‌ای دیگر می‌شود.

### نوع‌های مجموعه‌ای
نوع داده‌های مجموعه‌ای دارای دو دستهٔ دارای ترتیب  و بدون ترتیب (نگاشت یا ) هستند.
نوع داده‌های دارای ترتیب در بردارندهٔ مقادیر هستند که به صورتی مرتب پشت سر هم قرار گرفته‌اند. نمونهٔ این نوع داده‌ها لیست‌ها (آرایه‌های دینامیک)، توپل‌ها  و رشته‌ها هستند. اندیس گذاری در پایتون از ۰ شروع می‌شود. این نوع داده‌ها می‌توانند (بجز رشته‌ها) می‌توانند نوع داده‌های مختلف غیر یکسان را دربر گیرند. رشته‌ها و توپل‌ها تغییرناپذیر هستند. در صورتی که لیست‌ها و دیکشنری‌ها تغییرپذیر هستند. یعنی می‌توان آن‌ها را «در جا» ویرایش (حذف عنصر، اضافه کردن عنصر، عوض کردن مقدار، مرتب‌سازی …) کرد.
نوع داده‌های بدون ترتیب معمولاً به صورتی فرهنگ لغت هستند. یعنی مجموعه‌ای تغییرناپذیر را به مجموعهٔ از اشیا می‌نگارند؛ لذا در کل ترتیبی برای داده‌ها در نظر گرفته نمی‌شود. اشیایی که نگاشته می‌شوند (کلیدها یا ) باید از نوع تغییرناپذیر باشند، مانند اعداد صحیح یا یک رشته. این مسئله به خاطر آن است که در پشت صحنه، نگارش توسط یک تابع درهم سازی انجام می‌شود. تغییرناپذیر باعث می‌شود عملیات در بازدهی زمانی/حافظه‌ای بهتری انجام شوند؛ اگرچه لازم است که مقادیر آن‌ها ثابت بمانند؛ لذا چنین ساختاری «دیکشنری» نام دارد. نوع دادهٔ مشابه دیگر «مجموعه»  نام دارد که شامل تعداد شی بدون ترتیب است که بدون تکرار هستند، درست مانند تعریف ریاضی مجموعه‌ها؛ لذا به راحتی می‌توان از آن‌ها برای انجام عملیات مجموعه‌ای مانند اجتماع، اشتراک، تفاضل، تفاضل متقارن، زیر مجموعه‌گیری استفاده کرد.

### آیا متغیرهای پایتون فاقد نوع هستند؟
بعضی‌ها از اصطلاح فاقد نوع (untyped) برای متغیرهای پایتون (و دیگر زبان‌های دینامیک) استفاده می‌کنند که تعبیر غلطی است. این که در زبانی مانند C# تعریف متغیرها با اعلان نوع همراه باشد (مانند int x = 10) و در زبانی مانند پایتون نیاز به اعلان نوع نباشد (x=10)، به این معنی نیست که متغیرهای C# دارای نوع هستند و متغیرهای پایتون فاقد نوع. متغیرهای پایتون و هر زبان دیگر دارای نوع هستند؛ منتها تفاوت به استاتیک یا دینامیک بودن سیستم نوع برمی‌گردد که تعیین می‌کند که نوع متغیرها در طول برنامه قابل تغییر باشد یا خیر. پس، با وجودی که ما نوع متغیرهای پایتون را صراحتاً اعلان نمی‌کنیم، این متغیرها دارای نوع هستند و مفسر پایتون، نوع یک متغیر را از روی آخرین مقداری که دریافت کرده، استنتاج می‌کند.

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

## قواعد اولیه نگارش
### رشته‌ها
رشته‌ها گاه با `"` و گاه با `'` نوشته می‌شود و اگر شما در میان رشته نیز از `'` استفاده کردید بهتر است رشته را با `"` آغاز و پایان دهیم

#### اشاره‌کردن در رشته
می‌توان با استفاده از درصد در درون رشته یا استفاده از متد `format` چیزهایی را که به راحتی نمی‌توان درون رشته قرار داد یا پرینت کرد را درون رشته قرار دهیم:


```python
print(f"I just printed {num} pages to the printer {printer}")

print("I just printed {} pages to the printer {}".format(num, printer))
print("I just printed {0} pages to the printer {1}".format(num, printer))
print("I just printed {num} pages to the printer {printer}".format(num=num, printer=printer))

print("I just printed %s pages to the printer %s" % (num, printer))
print("I just printed %(num)s pages to the printer %(printer)s" % {"num": num, "printer": printer})
```


#### چاپ رشته‌ای چند سطر
برای این کار بهتر است از ۳تا `'` یا ۳تا`"`
نمونهٔ زیر چگونگی این کار را نشان می‌دهد:

```python
print("""Dear %(recipient)s,

I wish you to leave Sunnydale and never return.

Not Quite Love,
%(sender)s
""" % {'sender': 'Buffy the Vampire Slayer', 'recipient': 'Spike'})
```


#### رشته‌های خام
سرانجام، تمام رشته‌های قبلاً ذکر شده در گونه‌های «خام» قرار می‌گیرند (که با قرار دادن r به معنای واقعی کلمه قبل از نقل قول نشان داده می‌شوند)، که هیچ گونه تلاقی در درون نمی‌انجامد و از این رو برای عبارات منظم بسیار مفید هستند. "@ -quoting" را در C# مقایسه کنید. رشته‌های خام در ابتدا به‌طور خاص برای عبارات منظم درج شده بودند. با توجه به محدودیت‌های نشانه‌گذاری، رشته‌های خام ممکن است دارای خستگی برگشت‌ناپذیر نباشند. ایجاد یک رشته خام با نگه داشتن یک مسیر پنجره‌هایی که به صورت برگشتی به انتهای خود منتهی می‌شود، به انواع مختلفی از کار نیاز دارد (معمولاً استفاده از اسلش‌های جلو به جای بک لایت، زیرا پنجره هر دو را می‌پذیرد).


```pycon
>>> # A Windows path, even raw strings cannot end in a backslash
>>> r"C:\Foo\Bar\Baz\"
  File "<stdin>", line 1
    r"C:\Foo\Bar\Baz\"
                     ^
SyntaxError: EOL while scanning string literal

>>> dos_path = r"C:\Foo\Bar\Baz\ " # avoids the error by adding
>>> dos_path.rstrip()              # and removing trailing space
'C:\\Foo\\Bar\\Baz\\'

>>> quoted_dos_path = r'"{}"'.format(dos_path)
>>> quoted_dos_path
'"C:\\Foo\\Bar\\Baz\\ "'

>>> # A regular expression matching a quoted string with possible backslash quoting
>>> re.match(r'"(([^"\\]|\\.)*)"', quoted_dos_path).group(1).rstrip()
'C:\\Foo\\Bar\\Baz\\'

>>> code = 'foo(2, bar)'
>>> # Reverse the arguments in a two-arg function call
>>> re.sub(r'\(([^,]*?),([^ ,]*?)\)', r'(\2, \1)', code)
'foo(2, bar)'
>>> # Note that this won't work if either argument has parens or commas in it.
```


#### ادغام دو رشته
می‌توان دو رشته را به صورت زیر ادغام کرد:

```python
title = "One Good Turn: " \
        'A Natural History of the Screwdriver and the Screw'
```

که معادل است با عبارت زیر:

```python
title = "One Good Turn: A Natural History of the Screwdriver and the Screw"
```


### اعداد
در پایتون اعداد به فرم عادی مشابه سایز زبان‌ها تعریف می‌شوند، همچون  `0`, `-1`, `3.4`, `3.5e-8`.

عدد صحیح در پایتون طول دلخواه دارد و در صورت نیاز به‌طور خودکار فضای حافظه را زیاد می‌کند.
پایتون دارای نوع داده صحیح با محدودهٔ یکسان هستند. تا قبل از نسخهٔ ۳ پایتون، دو نوع عدد صحیح موجود بود، یکی اعداد صحیح عادی با طول ثابت، و دیگری اعداد صحیح با طول بلند یا "long" با طول دلخواه. اینکه از کدام نوع عدد صحیح استفاده شود، به صورتی خودکار توسط پایتون انجام می‌شد. در نسخه‌های جدید، نوع اول به‌طور کامل حذف شد.
اعداد حقیقی  به صورت عادی تعریف می‌شوند. استفاده از این نوع زمانی انجام می‌شود که از علامت نقطه به عنوان ممیز اعشار استفاده شود، مانند ۱٫۱.

### لیست‌ها، تاپل‌ها، مجموعه‌ها، دیکشنری‌ها
همان‌طور که گفته شد، لیست‌ها دارای ساختار تغییرپذیر هستند. لیست‌ها در کلاس `list` تعریف می‌شوند. نمونه‌ای از تعریف یک لیست به صورت زیر است:

```python
a_list = [1, 2, 3, "a dog"]
```

می‌توان لیست‌ها را همچون ایجاد یک شیء از یک کلاس تعریف کرد:

```python
a_second_list = list()
a_second_list.append(4)
a_second_list.append(5)
```


همان‌طور که گفته شد توپل‌ها `tuple` اعضایی تغییرناپذیر از پایتون هستند که در کلاس `tuple` تعریف می‌شوند.

```python
a_tuple = 1, 2, 3, "four"
```

اگرچه در تعریف فوق توپل توسط کاما بین اعضای آن تعریف می‌شود، می‌توان با قرار دادن پرانتز بین اعضای آن تعریف آن را قابل فهم تر می‌کند. یک توپل تهی به صورت () معرفی می‌شود.
مجموعه‌های نوع داده‌هایی قابل تغییر هستند که در کلاس `set` تعریف می‌شوند.

```python
some_set = {0, (), False}
```

دیکشنری‌ها نوع داده‌هایی تغییرپذیر هستند که در کلاس `dict` تعریف می‌شوند. در پایتون اعضای یک دیکشنری به صورت زوج `{key: value}` تعریف می‌شود.

```python
a_dictionary = {"key 1":"value 1", 2:3, 4:[]}
```


## عملگرها
### عملگرهای محاسباتی
عملگرهای محاسباتی شامل ، ، ، ،  (باقیمانده) و (توان) است. در استفاده از  برای تقسیم باید دقت کرد. به مثال زیر دقت کنید:

```python
def mean(seq):
    return sum(seq) / len(seq)
```

فراخوانی `mean([3.0, 4.0])` برمی‌گرداند. ممکن است `mean([3, 4])` را فراخوانی کنید و خروجی ۳ بگیرید که نتیجه‌ای عجیب است. دلیل این مسئله این است که تقسیم اعداد به صورت صحیح انجام شده و لذا نتیجه عددی صحیح است. راه چاره این است که تیکه برنامهٔ فوق را به صورات زیر تغییر دهیم:

```python
def mean(seq):
    return float(sum(seq)) / len(seq)
```

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

### عملگرهای مقایسه‌ای
* `== ` برای تشخیص آنکه ورودی با مقدار مقدار داده‌شده برابر است: `g == 2`
* `<>` (پایتون ۲) و `=!` (پایتون ۳) برای تشخیص مساوی‌نبودن ورودی و مقدار داده‌شده: `g != 2`
* `<` برای تشخیص بزرگتر بودن ورودی از مقدار و `=<` برای تشخیص بزرگتر یا مساوی بودن ورودی از مقدار.
* `>` برای تشخیص کوچکتر بودن ورودی از مقدار و `=>` برای تشخیص کوچکتر یا مساوی بودن ورودی از مقدار.
* `is` برای تشخیص هماهنگی ورودی و مقدار و `is not` برای تشخیص هماهنگی نبودن
* `in` برای تشخیص قرارداشتن مقدار در ورودی و `not in` برای تشخیص برعکس
در صورت درست بودن، به‌ما `True` و در غیر این صورت، `False` می‌دهد

## برنامه‌نویسی تابعی
سبک برنامه‌نویسی تابعی به سبکی از برنامه‌نویسی گفته می‌شود که در آن به صورتی به صورت‌هایی مؤثر تر از قابلیت‌های لیست‌ها و نوع داده‌های آن برای انجام عملیات نسبتاً پیچیده‌تر استفاده می‌شود.

### مرکب‌ها
لیست مرکب لیستی است که مقادیری به آن داده شده و همراه حلقه `for` درون لیست می‌توان آن مقادیر را تا جای ممکن تکرار کرد.

```python
L = [mapping_expression for element in source_list if filter_expression]
```

به عنوان مثال برنامهٔ زیر ۵ توان اول ۲ را توسط یک سطر کد محاسبه می‌کند:

```python
powers_of_two = [2**n for n in range(1, 6)]
```

به عنوان مثالی دیگر، برنامهٔ زیر (کوییک‌سورت) را به کوتاه (اگرچه غیر بهینه) انجام می‌دهد:

```python
def qsort(L):
    if L == []:
        return []
    pivot = L[0]
    return (qsort([x for x in L[1:] if x < pivot]) +
            [pivot] +
            qsort([x for x in L[1:] if x >= pivot]))
```

پایتون ۲٬۷+ همچنین مجموعه را به درستی تنظیم و پشتیبانی می‌کند و دیکشنری را تنظیم می‌کند.

### توابع کلاس‌اول
در پایتون، توابع کلاس اول هستند که می‌توانند به‌صورت دینامیکی ایجاد شده و به اطراف منتقل شوند.

پشتیبانی محدود پایتون از کارکردهای ناشناس، ساختار `lambda` است. برنامه زیر با کاراکتر ۵ اجرا می‌شود:

```python
f = lambda x: x**2
f(5)
```

لامبداها یک عمل را به‌جای چندین عمل انجام می‌دهد، اگرچه جریان کنترل هنوز هم با استفاده از اتصال کوتاه می‌تواند کمتر با ظرافت در لامبدا اجرا شود، و اصطلاحات بیشتری با عبارات شرطی دارند.

### بستارها
پایتون از نسخه ۲٬۲ از بستار پشتیبانی کرده‌است. در اینجا مثالی را می‌بینید:

```python
def derivative(f, dx):
    """Return a function that approximates the derivative of f
    using an interval of dx, which should be appropriately small.
    """
    def function(x):
        return (f(x + dx) - f(x)) / dx
    return function
```

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

توجه داشته باشید که بستارهای الزام‌آور از یک نام تاحدی قابل تغییر از درون تابع نیست. برای مثال:

```pycon
>>> def foo(a, b):
...     print('a: %r' % a)
...     print('b: %r' % b)
...     def bar(c):
...         b = c
...         print('b*: %r' % b)
...     bar(a)
...     print('b: %r' % b)

>>> foo(1,2)
a: 1
b: 2
b*: 1
b: 2
```

و شما می‌توانید آن را ببینید که `b`، همانند قابل مشاهده از بستارهای محدود، ارزش خود را حفظ می‌کند. ما می‌توانیم از `b` در داخل تابع استفاده کنیم اما بیرون از تابع نه. مگر آنکه از عبارت `nonlocal b` در تابع استفاده کرد. در پایتون ۲ (فاقد `nonlocal` در نسخه) راه حل معمول این است که از مقدارهای تغییرپذیر استفاده نمود و آن مقدار را تغییر داد، این کار الزام‌آور نیست. برای مثال، لیستی با یک عنصر را اشاره می‌کنیم.

### مولدها
در پایتون ۲٫۲ به عنوان یک ویژگی اختیاری معرفی و در نسخه ۲٫۳ نهایی شده‌است، مولد است که سازوکاری برای ارزیابی کندرو از یک تابع می‌باشد و در غیر این صورت یک فضای منع‌کننده یا لیست محاسباتی فشرده را برگشت می‌دهد.

این یک نمونه برای تولید کندرو نخستین عدد است:

```python
from itertools import count

def generate_primes(stop_at=0):
    primes = []
    for n in count(2):
        if 0 < stop_at < n:
            return # raises the StopIteration exception
        composite = False
        for p in primes:
            if not n % p:
                composite = True
                break
            elif p ** 2 > n:
                break
        if not composite:
            primes.append(n)
            yield n
```

برای استفاده از این تابع به سادگی تماس بگیرید، به‌عنوان مثال:

```python
for i in generate_primes():  # iterate over ALL primes
    if i > 100:
        break
    print(i)
```

تعریف از یک مولد با یک عملکرد همسان ظاهر می‌شود، به‌جز واژه کلیدی `yield` از `return` نیز در محل استفاده شده‌است. با این حال، یک مولد یک شیء با حالت مداوم است، که می‌توان بارها و بارها وارد و خارج از محدوده یکسان شد. سپس بایک تماس مولد می‌توان در محل از یک لیست استفاده کرد، یا دیگر ساختارهایی که عناصر در آن تکرار خواهد شد. هر زمان که حلقه `for` در مثال نیاز دارد به مورد بعدی برود، این مولد نامیده می‌شود، و محصول مورد بعدی را باز می‌دهد.

## دکوراتورها
دکوراتور شیء قابل فراخوانی‌ای است که به منظور پیرایش تعریف تابع کلاس یا متد استفاده می‌شود. کلیدواژهٔ `@` برای دکوراتور استفاده می‌شود.


```python
@viking_chorus
def menu_item():
    print("spam")
```


**که با کد زیر هم ارز است.**


```python
def menu_item():
    print("spam")
menu_item = viking_chorus(menu_item)
```


استفاده از دکوراتورها نوعی فرا برنامه‌نویسی است. دکوراتورها به منظور بهبود تابع یا متدی که روی آن اعمال می‌شوند استفاده می‌شوند. مثلاً در مثال پایین `viking_chorus` موجب می‌شود تابع `menu_item` هشت بار اجرا شود.


```python
def viking_chorus(myfunc):
    def inner_func(*args, **kwargs):
        for i in range(8):
            myfunc(*args, **kwargs)
    return inner_func
```


## منابع

رده:پایتون (زبان برنامه‌نویسی)
رده:کامپایلرها و مفسرهای آزاد
رده:نرم‌افزارهای آزاد چندسکویی