6. عبارات

این فصل معنای عناصر عبارت‌ها در پایتون را توضیح می‌دهد.

یادداشت‌های سینتکس: در این فصل و فصل‌های پس از آن، از نمادگذاری دستور زبان برای توصیف سینتکس استفاده خواهد شد، نه برای تحلیل واژگانی.

هنگامی که (یکی از جایگزین‌های) یک قاعده‌ی سینتکس به شکل زیر باشد:

name: othername

و هیچ معنایی ارائه نشده است، معنای این شکل از name همان معنای othername است.

6.1. تبدیلات حسابی

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

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

6.2. اتم‌ها

اتم‌ها اساسی‌ترین عناصر عبارت‌ها هستند. ساده‌ترین اتم‌ها ثابت‌های توکار، نام‌ها و لیترال‌ها هستند. اتم‌های پیچیده‌تر در درون جفت‌جداکننده‌ها قرار می‌گیرند:

به‌طور رسمی، سینتکس اتم‌ها عبارت است از:

atom:
   | builtin_constant
   | identifier
   | literal
   | parenthesized_enclosure
   | bracketed_enclosure
   | braced_enclosure
parenthesized_enclosure:
   | group
   | tuple
   | yield_atom
   | generator_expression
bracketed_enclosure:
   | listcomp
   | list
braced_enclosure:
   | dictcomp
   | dict
   | setcomp
   | set

6.2.1. ثابت‌های توکار

کلیدواژه‌های True، False و None نام‌های ثابت‌های توکار هستند. توکن ... نام ثابت Ellipsis است.

ارزیابی این اتم‌ها مقدار متناظر را به دست می‌دهد.

نکته

چند ثابت توکار دیگر نیز به‌عنوان متغیرهای سراسری در دسترس هستند، اما تنها مواردی که در اینجا ذکر شده‌اند کلیدواژه‌ها هستند. به‌ویژه، این نام‌ها را نمی‌توان دوباره مقداردهی کرد یا به‌عنوان ویژگی استفاده کرد:

>>> False = 123
  File "<input>", line 1
   False = 123
   ^^^^^
SyntaxError: cannot assign to False

به‌طور رسمی، نحوه (سینتکس) ثابت‌های توکار به این صورت است:

builtin_constant: 'True' | 'False' | 'None' | '...'

6.2.2. شناسه‌ها (نام‌ها)

یک شناسه که به‌عنوان یک اتم (atom) ظاهر می‌شود، یک نام است. بخش نام‌ها (شناسه‌ها و کلیدواژه‌ها) را برای تعریف واژگانی و بخش نام‌گذاری و مقیدسازی را برای مستندات نام‌گذاری و پیوند ببینید.

هنگامی که نام به یک شیء مقید شده باشد، ارزیابی اتم، آن شیء را حاصل می‌کند. هنگامی که نامی مقید نشده باشد، تلاش برای ارزیابی آن، استثنای NameError را پرتاب می‌کند.

6.2.2.1. تغییر نام خصوصی (private name mangling)

هرگاه شناسه‌ای که در متن تعریف یک کلاس آمده باشد با ۲ یا چند نویسه زیرخط آغاز شود و به ۲ یا چند زیرخط ختم نشود، یک نام خصوصی (private name) برای آن کلاس محسوب می‌شود.

همچنین ببینید

مشخصات کلاس.

دقیق‌تر اینکه، نام‌های خصوصی پیش از تولید کد برای آن‌ها به شکل طولانی‌تری تبدیل می‌شوند. اگر نام تبدیل‌شده طولانی‌تر از ۲۵۵ نویسه باشد، ممکن است کوتاه‌سازی (truncation) تعریف‌شده توسط پیاده‌سازی رخ دهد.

این تبدیل مستقل از زمینه‌ی نحوی‌ای است که شناسه در آن استفاده می‌شود، اما تنها شناسه‌های خصوصی زیر تغییر نام داده می‌شوند:

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

    با این حال، ویژگی __name__ در توابع، کلاس‌ها و نام‌های مستعار نوع تودرتو تغییر نام نمی‌یابد.

  • نام ماژول‌های ایمپورت‌شده، برای مثال __spam در import __spam. اگر ماژول بخشی از یک بسته باشد (یعنی نام آن شامل نقطه باشد)، نام دستکاری نمی‌شود، برای مثال __foo در import __foo.bar دستکاری نمی‌شود.

  • نام یک عضو ایمپورت‌شده، مثلاً __f در from spam import __f.

قاعده تبدیل به‌صورت زیر تعریف شده است:

  • نام کلاس، پس از حذف زیرسطرهای آغازین و افزودن یک زیرخط در ابتدا، در جلوی شناسه قرار می‌گیرد؛ برای مثال، شناسه‌ی __spam که در کلاسی با نام Foo، _Foo یا __Foo آمده باشد، به _Foo__spam تبدیل می‌شود.

  • اگر نام کلاس فقط از زیرخط تشکیل شده باشد، تبدیل همانی است؛ برای مثال، شناسه‌ی __spam که در کلاسی با نام _ یا __ آمده است، بدون تغییر باقی می‌ماند.

6.2.3. مقادیر لفظی

لفظی (literal) نمایشی متنی از یک مقدار است. پایتون از مقادیر لفظی عددی، رشته‌ای و بایتی پشتیبانی می‌کند. اف‌استرینگ‌ها و رشته‌های قالبی به‌عنوان مقادیر لفظی رشته‌ای در نظر گرفته می‌شوند.

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

مقادیر لفظی رشته و بایت ممکن است از چندین توکن تشکیل شده باشند. برای جزئیات، بخش الحاق رشته‌های لفظی را ببینید.

توجه داشته باشید که اعداد منفی و مختلط، مانند -3 یا 3+4.2j، از نظر سینتکسی لفظی نیستند، بلکه عملیات حسابی یک‌عملوندی یا دوعملوندی هستند که شامل عملگر - یا + می‌شوند.

ارزیابی یک لفظی، شیء‌ای از نوع داده‌شده (int، float، complex، str، bytes، یا Template) با مقدار داده‌شده را به دست می‌دهد. در مورد مقادیر لفظی ممیز شناور و موهومی، ممکن است مقدار تقریبی باشد.

دستور زبان صوری برای مقادیر لفظی چنین است:

literal: strings | NUMBER

6.2.3.1. مقادیر لفظی و هویت شیء

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

جزئیات پیاده‌سازی CPython

برای مثال، در CPython، اعداد صحیح کوچک با مقدار یکسان، به یک شیء یکسان ارزیابی می‌شوند:

>>> x = 7
>>> y = 7
>>> x is y
True

با این حال، اعداد صحیح بزرگ به اشیاء متفاوتی ارزیابی می‌شوند:

>>> x = 123456789
>>> y = 123456789
>>> x is y
False

این رفتار ممکن است در نسخه‌های آینده CPython تغییر کند. به‌ویژه، مرز بین اعداد صحیح «کوچک» و «بزرگ» پیش‌تر تغییر کرده است.

CPython هنگامی که مقادیر لفظی را با استفاده از is مقایسه می‌کنید، یک SyntaxWarning نشان می‌دهد:

>>> x = 7
>>> x is 7
<input>:1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
True

برای اطلاعات بیشتر، چه زمانی می‌توانم به آزمون‌های هویت با عملگر is اتکا کنم؟ را ببینید.

رشته‌های الگو تغییرناپذیر هستند، اما ممکن است به اشیای تغییرپذیر به‌عنوان مقادیر Interpolation ارجاع دهند. برای اهداف این بخش، دو تی‌استرینگ «مقدار یکسان» دارند اگر هم ساختار آن‌ها و هم هویت مقادیرشان مطابقت داشته باشد.

در حال حاضر، هر ارزیابی از یک رشته‌ی قالب به یک شیء متفاوت منجر می‌شود.

6.2.3.2. الحاق رشته‌های لفظی

مقادیر لفظی مجاور رشته یا بایت، که ممکن است از قواعد متفاوتی برای علامت نقل‌قول استفاده کنند، مجاز هستند و معنای آن‌ها همان معنای الحاق آن‌ها است:

>>> "hello" 'world'
"helloworld"

این قابلیت در سطح سینتکس تعریف شده است، بنابراین فقط با مقادیر لفظی کار می‌کند. برای الحاق عبارات رشته‌ای در ران‌تایم، می‌توان از عملگر '+' استفاده کرد:

>>> greeting = "Hello"
>>> space = " "
>>> name = "Blaise"
>>> print(greeting + space + name)   # not: print(greeting space name)
Hello Blaise

در الحاق لفظی می‌توان آزادانه رشته‌های خام، رشته‌های سه‌نقل‌قولی و مقادیر لفظی رشته‌ای قالب‌بندی‌شده را با هم ترکیب کرد. برای مثال:

>>> "Hello" r', ' f"{name}!"
"Hello, Blaise!"

می‌توان از این قابلیت برای کاهش تعداد بک‌اسلش‌های مورد نیاز، تقسیم راحت رشته‌های طولانی در سطرهای طولانی، یا حتی افزودن کامنت به بخش‌هایی از رشته‌ها استفاده کرد. برای مثال:

re.compile("[A-Za-z_]"       # letter or underscore
           "[A-Za-z0-9_]*"   # letter, digit or underscore
          )

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

>>> t"Hello" t"{name}!"
Template(strings=('Hello', '!'), interpolations=(...))

به‌طور رسمی:

strings: (STRING | fstring)+ | tstring+

6.2.4. گروه‌های پرانتزگذاری‌شده

یک گروه پرانتزدار عبارتی است که در پرانتز محصور شده است. این گروه به همان مقداری ارزیابی می‌شود که عبارت درون آن ارزیابی می‌شود.

گروه‌ها برای لغو یا شفاف‌سازی تقدم عملگر، به همان روش نمادگذاری ریاضی استفاده می‌شوند. برای مثال:

>>> 3 << 2 | 4
12
>>> 3 << (2 | 4)   # Override precedence of the | (bitwise OR)
192
>>> (3 << 2) | 4   # Same as without parentheses (but more clear)
12

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

به‌طور رسمی، نحوه (سینتکس) گروه‌ها به این صورت است:

group: '(' assignment_expression ')'

6.2.5. نمایش‌های ظروف

پایتون برای ساخت ظروف توکار (فهرست‌ها، مجموعه‌ها، تاپل‌ها یا دیکشنری‌ها)، نحو ویژه‌ای به نام نمایش‌ها (displays) فراهم می‌کند. تفاوت‌های ظریفی بین این چهار نوع نمایش وجود دارد که در بخش‌های زیر به تفصیل شرح داده شده است. با این حال، همه نمایش‌ها از آیتم‌های جدا شده با کاما تشکیل شده‌اند که در جداکننده‌های جفت‌شده محصور شده‌اند.

برای نمونه، یک نمایش فهرست (list display) مجموعه‌ای از عبارت‌ها است که در داخل کروشه‌ها قرار گرفته‌اند:

>>> ["one", "two", "three"]
['one', 'two', 'three']
>>> [1 + 2, 2 + 3]
[3, 5]

در نمایش‌های فهرست، تاپل و دیکشنری (اما نه مجموعه)، دنباله می‌تواند خالی باشد:

>>> []  # empty list
[]
>>> ()  # empty tuple
()
>>> {}  # empty dictionary
{}

اگر سری خالی نباشد، پس از آیتم‌ها می‌توان از یک ویرگول اضافی استفاده کرد که هیچ تأثیری ندارد:

>>> ["one", "two", "three",]  # note comma after "three"
['one', 'two', 'three']

نکته

ویرگول پایانی اغلب برای نمایش‌هایی استفاده می‌شود که چندین سطر را در بر می‌گیرند (با استفاده از implicit line joining)؛ بنابراین وقتی برنامه‌نویس آینده‌ای در انتهای آن ورودی جدیدی اضافه می‌کند، نیازی به تغییر سطر موجود ندارد:

>>> [
...     'one',
...     'two',
...     'three',
... ]
['one', 'two', 'three']

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

برای نمایش‌های تاپل، فهرست و مجموعه (اما نه دیکشنری)، هر آیتمی در نمایش می‌تواند پیشوندی با یک ستاره (*) داشته باشد. این موضوع نشان‌دهنده‌ی iterable unpacking است. در زمان ران‌تایم، عبارتِ پیشوندگرفته با ستاره باید به یک پیمایش‌پذیر ارزیابی شود که محتویات آن در محل بازکردن بسته در ظرف درج می‌شوند. برای مثال:

>>> numbers = (1, 2)
>>> [*numbers, 'word', *numbers]
[1, 2, 'word', 1, 2]

نمایش‌های دیکشنری از مکانیسم مشابه‌ای به نام بازکردن بسته‌ی دیکشنری استفاده می‌کنند که با دو ستاره (**) مشخص می‌شود. برای جزئیات بیشتر نمایش‌های دیکشنری را ببینید.

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

اضافه شده در نسخه‌ی 3.5: پیمایش‌پذیر و بازکردن بسته‌ی دیکشنری در نمایش‌ها که ابتدا توسط PEP 448 پیشنهاد شد.

6.2.5.1. نمایش‌های فهرست

یک نمایش فهرست (list display) دنباله‌ای احتمالاً خالی از عبارت‌ها است که در داخل کروشه‌ها قرار دارد. برای نمونه:

>>> ["one", "two", "three"]
['one', 'two', 'three']
>>> ["one"]  # One-element list
['one']
>>> []       # empty list
[]

برای اطلاعات عمومی درباره‌ی نمایش‌ها، نمایش‌های ظروف را ببینید.

گرامر رسمی نمایش‌های فهرست عبارت است از:

list: '[' [flexible_expression_list] ']'

6.2.5.2. نمایش‌های مجموعه

یک نمایش مجموعه (set display) دنباله‌ای غیرخالی از عبارت‌ها است که در داخل آکولادها قرار دارد. برای نمونه:

>>> {"one", "two", "three"}
{'one', 'three', 'two'}
>>> {"one"}  # One-element set
{'one'}

برای اطلاعات عمومی درباره‌ی نمایش‌ها، نمایش‌های ظروف را ببینید.

هیچ نحو خاصی برای مجموعه‌ی خالی وجود ندارد. لفظی {} یک dictionary display است که یک دیکشنری خالی می‌سازد. برای دریافت یک مجموعه‌ی خالی، set() را بدون هیچ آرگومانی فراخوانی کنید.

گرامر رسمی نمایش‌های مجموعه عبارت است از:

set: '{' flexible_expression_list '}'

6.2.5.3. نمایش‌های تاپل

یک نمایش تاپل (tuple display) دنباله‌ای از عبارت‌ها است که در داخل پرانتزها قرار دارد. برای نمونه:

>>> (1, 2)
(1, 2)
>>> ()  # an empty tuple
()

برای اطلاعات عمومی درباره‌ی نمایش‌ها، نمایش‌های ظروف را ببینید.

برای جلوگیری از ابهام، اگر یک نمایش تاپل دقیقاً یک عنصر داشته باشد، به یک ویرگول پایانی نیاز دارد. بدون آن، یک parenthesized group دریافت می‌کنید:

>>> ('single',)  # single-element tuple
('single',)
>>> ('single')   # no comma: single string
'single'

به عبارت دیگر، نمایش تاپل فهرستی است از موارد زیر که داخل پرانتز قرار گرفته‌اند:

  • دو یا چند عبارت جداشده با کاما، یا

  • صفر یا چند عبارت که هر کدام با یک ویرگول دنبال می‌شوند.

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

نکته

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

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

گرامر رسمی برای نمایش‌های تاپل عبارت است از:

tuple:
   | '(' flexible_expression (',' flexible_expression)+ [','] ')'
   | '(' flexible_expression ',' ')'
   | '(' ')'

6.2.5.4. نمایش‌های دیکشنری

یک dictionary display سری احتمالاً خالی از dict items است که درون آکولاد قرار گرفته‌اند. هر آیتم دیکشنری یک جفت عبارتِ جداشده با دونقطه است: key و value مرتبط با آن. برای مثال:

>>> {1: 'one', 2: 'two'}
{1: 'one', 2: 'two'}

در ران‌تایم، هنگام ارزیابی یک درک دیکشنری، عبارت‌ها از چپ به راست ارزیابی می‌شوند. هر شیء کلید به عنوان کلیدی در دیکشنری برای ذخیره‌ی مقدار متناظر استفاده می‌شود. این بدان معناست که شما می‌توانید یک کلید را چندین بار در درک مشخص کنید و مقدار دیکشنری نهایی برای یک کلید مشخص، آخرین مقداری خواهد بود که داده شده است. برای مثال:

>>> {
...     1: 'this will be overridden',
...     2: 'two',
...     1: 'also overridden',
...     1: 'one',
... }
{1: 'one', 2: 'two'}

به‌جای جفت کلید-مقدار، یک آیتم دیکشنری ممکن است عبارتی باشد که با دو ستاره ** پیشوند شده است. این نشان‌دهنده‌ی بازکردن بسته دیکشنری است. در ران‌تایم، عبارت باید به یک نگاشت ارزیابی شود؛ هر آیتم از نگاشت به دیکشنری جدید اضافه می‌شود. همانند جفت‌های کلید-مقدار، مقادیر بعدی جایگزین مقادیری می‌شوند که قبلاً توسط آیتم‌ها و بازکردن بسته‌های قبلی تنظیم شده‌اند. این ممکن است برای بازنویسی مجموعه‌ای از مقادیر پیش‌فرض استفاده شود:

>>> defaults = {'color': 'blue', 'count': 8}
>>> overrides = {'color': 'yellow'}
>>> {**defaults, **overrides}
{'color': 'yellow', 'count': 8}

اضافه شده در نسخه‌ی 3.5: واگشایی در نمایش‌های دیکشنری، که در ابتدا در PEP 448 پیشنهاد شده بود.

گرامر رسمی برای نمایش‌های دیکشنری عبارت است از:

dict:                   '{' [double_starred_kvpairs] '}'
double_starred_kvpairs: ','.double_starred_kvpair+ [',']
double_starred_kvpair:  '**' or_expr | kvpair
kvpair:                 expression ':' expression

6.2.6. درک‌ها

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

در ساده‌ترین شکل، یک درک‌کننده شامل یک عبارت واحد است که پس از آن یک بند for قرار دارد. بند for دارای همان نحو (سینتکس) سرآیند یک دستور for است، بدون اینکه دو‌نقطه در انتهای آن قرار گیرد.

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

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

در زمان اجرا، یک درک فهرستی یک فهرست جدید ایجاد می‌کند. عبارت پس از in باید به یک پیمایش‌پذیر ارزیابی شود. برای هر عنصر از این پیمایش‌پذیر، عنصر به هدف بند for مانند یک دستور for متصل می‌شود، سپس عبارت قبل از for با هدف در محدوده ارزیابی می‌شود و نتیجه به فهرست جدید اضافه می‌شود. بنابراین، مثال بالا تقریباً معادل تعریف و فراخوانی تابع زیر است:

def make_list_of_squares(iterable):
    result = []
    for x in iterable:
        result.append(x**2)
    return result

make_list_of_squares(range(10))

درک‌های مجموعه نیز به همین صورت کار می‌کنند. برای مثال، این هم مجموعه‌ای از حروف کوچک است:

>>> {x.lower() for x in ['a', 'A', 'b', 'C']}
{'c', 'a', 'b'}

در زمان اجرا، این کار تقریباً معادل فراخوانی این تابع است:

def make_lowercase_set(iterable):
    result = set(iterable)
    for x in iterable:
        result.append(x.lower())
    return result

make_lowercase_set(['a', 'A', 'b', 'C'])

درک‌های دیکشنری به جای یک عبارت، با یک جفت کلید-مقدار جدا شده با دو‌نقطه شروع می‌شوند. برای مثال:

>>> {func.__name__: func for func in [print, hex, any]}
{'print': <built-in function print>,
 'hex': <built-in function hex>,
 'any': <built-in function any>}

در زمان اجرا، این تقریباً معادل موارد زیر است:

def make_dict_mapping_names_to_functions(iterable):
    result = {}
    for func in iterable:
        result[func.__name__] = func
    return result

iterable([print, hex, any])

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

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

>>> tuple(x**2 for x in range(10))
(0, 1, 4, 9, 16, 25, 36, 49, 64, 81)

تغییر یافته در نسخه‌ی 3.8: پیش از پایتون 3.8، در درک دیکشنری، ترتیب ارزیابی کلید و مقدار به‌خوبی تعریف‌نشده بود. در CPython، مقدار پیش از کلید ارزیابی می‌شد. از 3.8 به بعد، کلید پیش از مقدار ارزیابی می‌شود، همان‌طور که در PEP 572 پیشنهاد شده است.

6.2.6.1. فیلتر کردن در درک‌ها

ممکن است پس از بند for یک بند if همراه با یک عبارت بیاید.

برای مثال، فهرستی از نام‌های ماژول math که با f شروع می‌شوند عبارت است از:

>>> [name for name in vars(math) if name.startswith('f')]
['fabs', 'factorial', 'floor', 'fma', 'fmod', 'frexp', 'fsum']

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

def get_math_f_names(iterable):
    result = []
    for name in iterable:
        if name.startswith('f'):
           result.append(name)
    return result

get_math_f_names(vars(math))

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

6.2.6.2. درک‌های پیچیده

به‌طور کلی، بند اول for در یک درک ممکن است با صفر یا چند بند اضافی for یا if دنبال شود. برای مثال، در اینجا فهرستی از نام‌های عرضه‌شده توسط دو ماژول پایتون آورده شده است که فیلتر شده‌اند تا فقط نام‌های شروع‌شونده با a را شامل شوند:

>>> import array
>>> import math
>>> [
...     name
...     for module in [array, math]
...     for name in vars(module)
...     if name.startswith('a')
... ]
['array', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh']

در زمان اجرا، این مورد تقریباً با تعریف و فراخوانی زیر مطابقت دارد:

def get_a_names(iterable):
    result = []
    for module in iterable:
        for name in vars(module):
            if name.startswith('a'):
                result.append(name)
    return result

get_a_names([array, math])

عناصر ظرف جدید آنهایی هستند که با در نظر گرفتن هر یک از بندهای for یا if به عنوان یک بلوک، تودرتو کردن از چپ به راست، و ارزیابی عبارت برای تولید یک عنصر (یا ورودی دیکشنری) در هر بار رسیدن به داخلی‌ترین بلوک، تولید می‌شوند.

به‌جز عبارت پیمایش‌پذیر در سمت چپ‌ترین بند for، درک در یک محدوده‌ی تودرتوی ضمنی جداگانه اجرا می‌شود. این تضمین می‌کند که نام‌های تخصیص‌یافته در فهرست هدف به محدوده‌ی احاطه‌کننده «نشت» نکنند. برای مثال:

>>> x = 'old value'
>>> [x**2 for x in range(10)]  # این `x` نسبت به درک محلی است
>>> x
'old value'

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

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

برای اطمینان از اینکه درک همیشه به ظرفی از نوع مناسب منجر می‌شود، عبارت‌های yield و yield from در محدوده‌ی تودرتوی ضمنی ممنوع هستند.

عبارت‌های انتساب در عبارت‌های پیمایش‌پذیر درک (یعنی عبارت‌های بعد از کلیدواژهین in) و همچنین در هیچ‌یک از درک‌هایی که مستقیماً در تعریف یک کلاس ظاهر می‌شوند، مجاز نیستند.

تغییر یافته در نسخه‌ی 3.8: yield و yield from در محدوده‌ی تودرتوی ضمنی ممنوع است.

6.2.6.3. بازکردن بسته در درک‌ها

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

این کار اغلب برای «تخت‌سازی» فهرست‌ها استفاده می‌شود، برای مثال:

>>> students = ['Petr', 'Blaise', 'Jarka']
>>> teachers = ['Salim', 'Bartosz']
>>> lists_of_people = [students, teachers]
>>> [*people for people in lists_of_people]
['Petr', 'Blaise', 'Jarka', 'Salim', 'Bartosz']

در زمان اجرا، این درک تقریباً با موارد زیر مطابقت دارد:

def flatten_names(lists_of_people):
    result = []
    for people in lists_of_people:
        result.extend(people)
    return result

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

برای مثال:

>>> system_defaults = {'color': 'blue', 'count': 8}
>>> user_defaults = {'color': 'yellow'}
>>> overrides = {'count': 5}

>>> configuration_sets = [system_defaults, user_defaults, overrides]

>>> {**d for d in configuration_sets}
{'color': 'yellow', 'count': 5}

اضافه شده در نسخه‌ی 3.15: بازکردن بسته در درک‌ها با استفاده از عملگرهای * و ** در PEP 798 معرفی شد.

6.2.6.4. درک‌های ناهمگام

در یک تابع async def، می‌توان از یک بند async for برای پیمایش روی یک پیمایش‌گر ناهمگام استفاده کرد. یک درک در یک تابع async def ممکن است شامل یک بند for یا async for به دنبال عبارت پیشرو باشد، ممکن است حاوی بندهای for یا async for اضافی باشد، و همچنین ممکن است از عبارت‌های await استفاده کند.

اگر یک درک حاوی بندهای async for باشد، یا اگر حاوی عبارت‌های await یا سایر درک‌های ناهمگام در هر جایی به‌جز عبارت پیمایش‌پذیر در سمت چپ‌ترین بند for باشد، به آن درک ناهمگام گفته می‌شود. یک درک ناهمگام ممکن است اجرای تابع هم‌روالی را که در آن ظاهر می‌شود، به حالت تعلیق درآورد.

اضافه شده در نسخه‌ی 3.6: درک‌های ناهمگام در PEP 530 معرفی شدند.

تغییر یافته در نسخه‌ی 3.11: درک‌های ناهمگام اکنون در داخل درک‌ها در توابع ناهمگام مجاز هستند. درک‌های بیرونی به‌طور ضمنی ناهمگام می‌شوند.

6.2.6.5. گرامر رسمی برای درک‌ها

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

listcomp:      '[' comprehension ']'
setcomp:       '{' comprehension '}'
comprehension: flexible_expression for_if_clause+

dictcomp:
    | '{' kvpair for_if_clause+ '}'
    | '{' '**' expression for_if_clause+ '}'

for_if_clause:
    | ['async'] 'for' target_list 'in' or_test ('if' or_test)*

6.2.7. عبارت‌های تولیدگر

سینتکس عبارت‌های تولیدگر (generator expressions) همانند درک‌های فهرستی است، با این تفاوت که آن‌ها به جای کروشه در پرانتز قرار می‌گیرند. برای مثال:

>>> iterator = (x ** 2 for x in range(10))
>>> iterator
<generator object <genexpr> at ...>

در ران‌تایم، یک عبارت تولیدگر به یک generator iterator ارزیابی می‌شود که همان مقادیرِ درک فهرستی متناظر را تولید می‌کند:

>>> list(iterator)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

بنابراین، مثال بالا تقریباً معادل تعریف و فراخوانی تابع تولیدگر زیر است:

def make_generator_of_squares(iterator):
    for x in iterator:
        yield x ** 2

make_generator_of_squares(iter(range(10)))

هنگامی که عبارت تولیدگر تنها آرگومان جایگاهی باشد و هیچ آرگومان کلیدواژه‌ای وجود نداشته باشد، می‌توان پرانتزهای دربرگیرنده را در فراخوانی‌ها حذف کرد. برای جزئیات، بخش فراخوانی‌ها را ببینید. برای مثال:

# The parentheses after `sum` are part of the call syntax:
>>> sum(x ** 2 for x in range(10))
285

# The generator needs its own parentheses if it's not the only argument:
>>> sum((x ** 2 for x in range(10)), start=1000)
1285

عبارت پیمایش‌پذیر در چپ‌ترین بند for بلافاصله ارزیابی می‌شود، به‌طوری که خطایی که این عبارت پرتاب می‌کند، در نقطه‌ای که عبارت تولیدگر تعریف می‌شود بروز می‌کند، نه در نقطه‌ای که نخستین مقدار بازیابی می‌شود:

>>> (x ** 2 for x in nonexistent_iterable)
Traceback (most recent call last):
  ...
NameError: name 'nonexistent_iterable' is not defined

پس از ارزیابی عبارت، یک پیمایش‌گر از نتیجه ایجاد می‌شود، گویی که iter() بر روی آن فراخوانی شده است. هر خطایی که هنگام ایجاد پیمایش‌گر پرتاب شود نیز بلافاصله منتشر می‌شود:

>>> (x ** 2 for x in None)
Traceback (most recent call last):
  ...
TypeError: 'NoneType' object is not iterable

تمام عبارت‌های دیگر به‌صورت تنبل ارزیابی می‌شوند، به همان شیوه‌ی تولیدگرهای معمولی (یعنی زمانی که از پیمایش‌گر خواسته شود مقداری را yield کند):

>>> iterator = (nonexistent_value for x in range(10))
>>> iterator
<generator object <genexpr> at ...>
>>> list(iterator)
Traceback (most recent call last):
  ...
NameError: name 'nonexistent_value' is not defined
>>> iterator = (x * y for x in range(10) for y in nonexistent_iterable)
>>> iterator
<generator object <genexpr> at ...>
>>> list(iterator)
Traceback (most recent call last):
  ...
NameError: name 'nonexistent_iterable' is not defined

برای جلوگیری از اخلال در عملکرد مورد انتظار خود عبارت تولیدگر، عبارت‌های yield و yield from در محدوده تودرتوی ضمنی ممنوع هستند.

اگر یک عبارت تولیدگر شامل بندهای async for یا عبارات await باشد، به آن عبارت تولیدگر ناهمگام (asynchronous generator expression) گفته می‌شود. یک عبارت تولیدگر ناهمگام یک شیء تولیدگر ناهمگام جدید برمی‌گرداند که یک پیمایش‌گر ناهمگام است (به پیمایش‌گرهای ناهمگام مراجعه کنید).

دستور زبان صوری عبارت‌های تولیدگر:

generator_expression: "(" comprehension ")"

اضافه شده در نسخه‌ی 3.6: عبارات تولیدگر ناهمگام معرفی شدند.

تغییر یافته در نسخه‌ی 3.7: پیش از پایتون 3.7، عبارات تولیدگر ناهمگام فقط می‌توانستند در هم‌روال‌های async def ظاهر شوند. از 3.7 به بعد، هر تابعی می‌تواند از عبارات تولیدگر ناهمگام استفاده کند.

تغییر یافته در نسخه‌ی 3.8: yield و yield from در محدوده‌ی تودرتوی ضمنی ممنوع است.

6.2.8. عبارت‌های yield

yield_atom:       "(" yield_expression ")"
yield_from:       "yield" "from" expression
yield_expression: "yield" yield_list | yield_from

عبارت yield هنگام تعریف یک تابع تولیدگر یا یک تابع تولیدگر ناهمگام استفاده می‌شود و بنابراین فقط می‌تواند در بدنه‌ی تعریف یک تابع استفاده شود. استفاده از عبارت yield در بدنه‌ی یک تابع، آن تابع را به یک تابع تولیدگر تبدیل می‌کند، و استفاده از آن در بدنه‌ی یک تابع async def، آن تابع هم‌روال را به یک تابع تولیدگر ناهمگام تبدیل می‌کند. برای مثال:

def gen():  # defines a generator function
    yield 123

async def agen(): # defines an asynchronous generator function
    yield 123

به دلیل عوارض جانبی عبارات yield بر محدوده‌ی دربرگیرنده، این عبارات مجاز نیستند بخشی از محدوده‌هایی باشند که به‌طور ضمنی برای پیاده‌سازی درک‌ها و عبارات تولیدگر تعریف شده‌اند.

تغییر یافته در نسخه‌ی 3.8: عبارات yield در محدوده‌های تودرتوی ضمنی که برای پیاده‌سازی درک‌ها و عبارات تولیدگر به کار می‌روند، ممنوع است.

توابع تولیدگر در ادامه توضیح داده شده‌اند، در حالی که توابع تولیدگر ناهمگام به‌طور جداگانه در بخش توابع تولیدگر ناهمگام توضیح داده شده‌اند.

هنگامی که یک تابع تولیدگر فراخوانی می‌شود، یک پیمایش‌گر برمی‌گرداند که به‌عنوان تولیدگر شناخته می‌شود. سپس آن تولیدگر اجرای تابع تولیدگر را کنترل می‌کند. اجرا زمانی آغاز می‌شود که یکی از متدهای تولیدگر فراخوانی شود. در آن هنگام، اجرا به نخستین عبارت yield می‌رسد، جایی که دوباره معلق می‌شود و مقدار yield_list را به فراخواننده‌ی تولیدگر برمی‌گرداند، یا اگر yield_list حذف شده باشد، None را برمی‌گرداند. منظور از معلق بودن این است که تمام وضعیت محلی حفظ می‌شود، از جمله انتساب‌های کنونی متغیرهای محلی، اشاره‌گر دستور، پشته‌ی ارزیابی داخلی، و وضعیت هرگونه مدیریت استثنا. هنگامی که اجرا با فراخوانی یکی از متدهای تولیدگر از سر گرفته می‌شود، تابع می‌تواند دقیقاً به‌گونه‌ای پیش برود که گویی عبارت yield تنها یک فراخوانی خارجی دیگر باشد. مقدار عبارت yield پس از آنکه اجرا از سر گرفته شد، به متدی بستگی دارد که اجرا را از سر گرفته است. اگر از __next__() استفاده شود (معمولاً از طریق for یا تابع توکار next())، نتیجه None است. در غیر این صورت، اگر از send() استفاده شود، نتیجه مقداری خواهد بود که به آن متد ارسال شده است.

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

عبارت‌های yield در هر جای یک ساختار try مجاز هستند. اگر تولیدگر پیش از نهایی شدن (با رسیدن تعداد ارجاع‌ها به صفر یا زباله‌روبی شدن) از سر گرفته نشود، متد close() پیمایش‌گر تولیدگر فراخوانی می‌شود تا امکان اجرای هر بند finally در انتظار فراهم شود.

هنگامی که از yield from <expr> استفاده می‌شود، عبارت ارائه‌شده باید پیمایش‌پذیر باشد. مقادیری که با پیمایش آن پیمایش‌پذیر تولید می‌شوند، مستقیماً به فراخواننده‌ی متدهای تولیدگر فعلی ارسال می‌شوند. هر مقداری که با send() ارسال شود و هر استثنایی که با throw() ارسال شود، در صورتی که پیمایش‌گر زیرین متدهای مناسب را داشته باشد، به آن ارسال می‌شود. در غیر این صورت، send() استثناهای AttributeError یا TypeError را پرتاب می‌کند، در حالی که throw() فقط استثنای ارسال‌شده را بلافاصله پرتاب می‌کند.

هنگامی که پیمایش‌گر زیربنایی به پایان می‌رسد، ویژگی value از نمونه‌ی پرتاب‌شده‌ی StopIteration به مقدار عبارت yield تبدیل می‌شود. این ویژگی می‌تواند یا هنگام پرتاب StopIteration به‌صراحت تنظیم شود، یا وقتی زیرپیمایش‌گر یک تولیدگر باشد به‌طور خودکار (با برگرداندن یک مقدار از زیرتولیدگر) تنظیم شود.

تغییر یافته در نسخه‌ی 3.3: yield from <expr> افزوده شد تا جریان کنترل به یک زیرپیمایش‌گر (subiterator) واگذار شود.

هنگامی که عبارت yield تنها عبارت در سمت راست یک دستور انتساب باشد، می‌توان پرانتزها را حذف کرد.

همچنین ببینید

PEP 255 - تولیدگرهای ساده

پیشنهاد برای افزودن تولیدگرها و دستور yield به پایتون.

PEP 342 - هم‌روال‌ها از طریق تولیدگرهای بهبودیافته

پیشنهادی برای بهبود API و سینتکس تولیدگرها، تا بتوان از آن‌ها به‌عنوان هم‌روال‌های ساده استفاده کرد.

PEP 380 - سینتکس واگذاری به یک زیرتولیدگر

پیشنهاد برای معرفی سینتکس yield_from، که واگذاری به زیرتولیدگرها را آسان می‌کند.

PEP 525 - تولیدگرهای ناهمگام

پیشنهادی که PEP 492 را با افزودن قابلیت‌های تولیدگر به توابع هم‌روال گسترش داد.

6.2.8.1. مثال‌ها

در اینجا یک مثال ساده آمده است که رفتار تولیدگرها و توابع تولیدگر را نشان می‌دهد:

>>> def echo(value=None):
...     print("Execution starts when 'next()' is called for the first time.")
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception as e:
...                 value = e
...     finally:
...         print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> print(next(generator))
Execution starts when 'next()' is called for the first time.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.

برای مثال‌هایی که از yield from استفاده می‌کنند، به PEP 380: سینتکس واگذاری به زیرتولیدگر در «تازه‌های پایتون» مراجعه کنید.

6.2.8.2. توابع تولیدگر ناهمگام

وجود عبارت yield در تابع یا متدی که با async def تعریف شده است، آن تابع را به‌عنوان یک تابع تولیدگر ناهمگام نیز تعریف می‌کند.

هنگامی که یک تابع تولیدگر ناهمگام فراخوانی می‌شود، یک پیمایش‌گر ناهمگام را بازمی‌گرداند که به‌عنوان یک شیء تولیدگر ناهمگام شناخته می‌شود. سپس آن شیء اجرای تابع تولیدگر را کنترل می‌کند. یک شیء تولیدگر ناهمگام به‌طور معمول در یک دستور async for در یک تابع هم‌روال استفاده می‌شود، همان‌گونه که یک شیء تولیدگر در یک دستور for استفاده می‌شود.

فراخوانی یکی از متدهای تولیدگر ناهمگام یک شیء awaitable بازمی‌گرداند و اجرا هنگامی آغاز می‌شود که این شیء await شود. در آن هنگام، اجرا به نخستین عبارت yield می‌رسد، جایی که دوباره معلق می‌شود و مقدار yield_list را به هم‌روال در انتظار بازمی‌گرداند. مانند یک تولیدگر، تعلیق به این معناست که تمام وضعیت محلی حفظ می‌شود، از جمله پیوندهای فعلی متغیرهای محلی، اشاره‌گر دستور، پشته ارزیابی داخلی و وضعیت هرگونه مدیریت استثنا. هنگامی که اجرا با await کردن شیء بعدی که توسط متدهای تولیدگر ناهمگام بازمی‌گردد، از سر گرفته شود، تابع می‌تواند دقیقاً همان‌طور پیش برود که گویی عبارت yield صرفاً یک فراخوانی خارجی دیگر باشد. مقدار عبارت yield پس از ازسرگیری، به متدی بستگی دارد که اجرا را از سر گرفته است. اگر از __anext__() استفاده شود، نتیجه None است. در غیر این صورت، اگر از asend() استفاده شود، نتیجه مقداری خواهد بود که به آن متد ارسال شده است.

اگر یک تولیدگر ناهمگام با break، لغو شدن وظیفه فراخوان، یا سایر استثناها پیش از موعد خارج شود، کد پاک‌سازی ناهمگام تولیدگر اجرا خواهد شد و ممکن است در زمینه‌ای غیرمنتظره استثناهایی را پرتاب کند یا به متغیرهای زمینه دسترسی یابد—شاید پس از پایان عمر وظایفی که به آن‌ها وابسته است، یا در جریان خاموش شدن حلقه‌ی رویداد، هنگامی که قلاب زباله‌روبی تولیدگر ناهمگام فراخوانی می‌شود. برای جلوگیری از این موضوع، فراخوان باید به‌صراحت با فراخوانی متد aclose() تولیدگر ناهمگام را ببندد تا تولیدگر را نهایی‌سازی کند و در نهایت آن را از حلقه‌ی رویداد جدا کند.

در یک تابع تولیدگر ناهمگام، عبارت‌های yield در هر جایی از ساختار try مجاز هستند. با این حال، اگر یک تولیدگر ناهمگام پیش از نهایی شدن (با رسیدن شمار ارجاع به صفر یا با زباله‌روبی شدن) از سر گرفته نشود، آنگاه یک عبارت yield درون ساختار try ممکن است منجر به اجرا نشدن بندهای finally در انتظار اجرا شود. در این حالت، بر عهده حلقه رویداد یا زمان‌بندِ در حال اجرای تولیدگر ناهمگام است که متد aclose() پیمایش‌گر تولیدگر ناهمگام را فراخوانی کند و شیء هم‌روال حاصل را اجرا کند، تا بدین ترتیب امکان اجرای هر بند finally در انتظار اجرا فراهم شود.

برای رسیدگی به نهایی‌سازی هنگام پایان حلقه رویداد، یک حلقه رویداد باید یک تابع نهایی‌ساز (finalizer) تعریف کند که یک پیمایش‌گرٔ تولیدگر ناهمگام را می‌گیرد و احتمالاً aclose() را فراخوانی می‌کند و هم‌روال را اجرا می‌نماید. این نهایی‌ساز را می‌توان با فراخوانی sys.set_asyncgen_hooks() ثبت کرد. یک پیمایش‌گرٔ تولیدگر ناهمگام در نخستین پیمایش، نهایی‌ساز ثبت‌شده را ذخیره می‌کند تا در زمان نهایی‌سازی فراخوانی شود. برای دیدن یک نمونه‌ی مرجع از متد نهایی‌ساز، پیاده‌سازی asyncio.Loop.shutdown_asyncgens در Lib/asyncio/base_events.py را ببینید.

عبارت yield from <expr> هنگام استفاده در یک تابع تولیدگر ناهمگام، خطای نحوی است.

6.3. اولیه‌ها

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

primary: atom | attributeref | subscription | call

6.3.1. ارجاع‌های ویژگی

ارجاع به ویژگی یک عبارت اصلی است که پس از آن یک نقطه و یک نام می‌آید:

attributeref: primary "." identifier

عبارت اصلی باید به شیء‌ای از نوعی ارزیابی شود که از ارجاع‌های ویژگی پشتیبانی می‌کند؛ بیشتر اشیاء نیز چنین هستند. سپس از این شیء خواسته می‌شود ویژگی‌ای با نام آن شناسه تولید کند. نوع و مقدار تولیدشده توسط شیء تعیین می‌شود. ارزیابی‌های متعدد یک ارجاع ویژگی یکسان ممکن است اشیاء متفاوتی تولید کنند.

این تولید را می‌توان با بازنویسی متد __getattribute__() یا متد __getattr__() سفارشی‌سازی کرد. متد __getattribute__() ابتدا فراخوانی می‌شود و یا مقداری را برمی‌گرداند یا در صورت در دسترس نبودن ویژگی، AttributeError را پرتاب می‌کند.

اگر یک AttributeError پرتاب شود و شیء متد __getattr__() داشته باشد، آن متد به‌عنوان جایگزین فراخوانی می‌شود.

6.3.2. زیرنویسی‌ها و اسلایس کردن‌ها

سینتکس زیرنویسی (subscription) معمولاً برای انتخاب یک عنصر از یک ظرف استفاده می‌شود -- برای مثال، برای دریافت یک مقدار از یک dict:

>>> digits_by_name = {'one': 1, 'two': 2}
>>> digits_by_name['two']  # Subscripting a dictionary using the key 'two'
2

در سینتکس زیرنویسی (subscription)، پس از شیء مورد زیرنویسی — یک اولیه — یک زیرنویس (subscript) در کروشه‌های مربع قرار می‌گیرد. در ساده‌ترین حالت، زیرنویس یک عبارت واحد است.

بسته به نوع شیءای که زیرنویس بر آن اعمال می‌شود، زیرنویس گاهی کلید (برای نگاشت‌ها)، اندیس (برای دنباله‌ها)، یا آرگومان نوع (برای انواع عام) نامیده می‌شود. از نظر سینتکسی، همه این‌ها معادل هستند:

>>> colors = ['red', 'blue', 'green', 'black']
>>> colors[3]  # Subscripting a list using the index 3
'black'

>>> list[str]  # Parameterizing the list type using the type argument str
list[str]

در ران‌تایم، مفسر عبارت اصلی و زیرنویس را ارزیابی می‌کند و __getitem__() یا __class_getitem__() آن را که متد ویژه است، با زیرنویس به‌عنوان آرگومان فراخوانی می‌کند. برای جزئیات بیشتر درباره‌ی این‌که کدام‌یک از این متدها فراخوانی می‌شود، __class_getitem__ در برابر __getitem__ را ببینید.

برای نشان دادن چگونگی کار زیرنویسی، می‌توانیم یک شیء سفارشی تعریف کنیم که __getitem__() را پیاده‌سازی می‌کند و مقدار زیرنویس را چاپ می‌کند:

>>> class SubscriptionDemo:
...     def __getitem__(self, key):
...         print(f'subscripted with: {key!r}')
...
>>> demo = SubscriptionDemo()
>>> demo[1]
subscripted with: 1
>>> demo['a' * 3]
subscripted with: 'aaa'

برای جزئیات مربوط به نحوه‌ی مدیریت زیرنویسی توسط انواع توکار، مستندات __getitem__() را ببینید.

از زیرنویسی‌ها نیز می‌توان به‌عنوان هدف در دستورهای انتساب یا حذف استفاده کرد. در این موارد، مفسر به‌ترتیب به‌جای __getitem__()، متد ویژه __setitem__() یا __delitem__() شیء مورد زیرنویسی را فراخوانی می‌کند.

>>> colors = ['red', 'blue', 'green', 'black']
>>> colors[3] = 'white'  # Setting item at index
>>> colors
['red', 'blue', 'green', 'white']
>>> del colors[3]  # Deleting item at index 3
>>> colors
['red', 'blue', 'green']

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

6.3.2.1. اسلایس‌ها

شکل پیشرفته‌تری از زیرنویسی، یعنی اسلایس کردن (slicing)، معمولاً برای استخراج بخشی از یک دنباله استفاده می‌شود. در این حالت، زیرنویس یک اسلایس است: حداکثر سه عبارت که با دونقطه از یکدیگر جدا شده‌اند. هر یک از عبارت‌ها ممکن است حذف شود، اما یک اسلایس باید دست‌کم شامل یک دونقطه باشد:

>>> number_names = ['zero', 'one', 'two', 'three', 'four', 'five']
>>> number_names[1:3]
['one', 'two']
>>> number_names[1:]
['one', 'two', 'three', 'four', 'five']
>>> number_names[:3]
['zero', 'one', 'two']
>>> number_names[:]
['zero', 'one', 'two', 'three', 'four', 'five']
>>> number_names[::2]
['zero', 'two', 'four']
>>> number_names[:-3]
['zero', 'one', 'two']
>>> del number_names[4:]
>>> number_names
['zero', 'one', 'two', 'three']

هنگامی که یک اسلایس ارزیابی می‌شود، مفسر یک شیء slice ایجاد می‌کند که ویژگی‌های start، stop و step آن به‌ترتیب نتایج عبارت‌های بین دونقطه‌ها هستند. هر عبارت جاافتاده به None ارزیابی می‌شود. سپس این شیء slice به __getitem__() یا __class_getitem__() متد خاص، همان‌طور که در بالا ذکر شد، داده می‌شود.

# continuing with the SubscriptionDemo instance defined above:
>>> demo[2:3]
subscripted with: slice(2, 3, None)
>>> demo[::'spam']
subscripted with: slice(None, None, 'spam')

6.3.2.2. زیرنویس‌های جداشده با ویرگول

همچنین می‌توان زیرنویس را به‌صورت دو یا چند عبارت یا اسلایس جداشده با کاما نیز مشخص کرد:

# continuing with the SubscriptionDemo instance defined above:
>>> demo[1, 2, 3]
subscripted with: (1, 2, 3)
>>> demo[1:2, 3]
subscripted with: (slice(1, 2, None), 3)

این شکل معمولاً با کتابخانه‌های عددی برای اسلایس داده‌های چندبُعدی استفاده می‌شود. در این حالت، مفسر یک tuple از نتایج عبارت‌ها یا اسلایس‌ها می‌سازد و این tuple را به متد ویژه __getitem__() یا __class_getitem__()، همان‌طور که در بالا آمد، ارسال می‌کند.

همچنین می‌توان زیرنویس را به‌صورت یک عبارت یا اسلایس تنها به‌همراه ویرگولی پس از آن، برای مشخص کردن یک تاپل تک‌عضوی به کار برد:

>>> demo['spam',]
subscripted with: ('spam',)

6.3.2.3. زیرنویسی‌های «ستاره‌دار»

اضافه شده در نسخه‌ی 3.11: عبارت‌های درون tuple_slices می‌توانند ستاره‌دار باشند. PEP 646 را ببینید.

عبارت زیرنویس می‌تواند شامل یک عبارت ستاره‌دار نیز باشد. در این حالت، مفسر نتیجه را در قالب یک تاپل واگشایی می‌کند و این تاپل را به __getitem__() یا __class_getitem__() منتقل می‌کند:

# continuing with the SubscriptionDemo instance defined above:
>>> demo[*range(10)]
subscripted with: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

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

>>> demo['a', 'b', *range(3), 'c']
subscripted with: ('a', 'b', 0, 1, 2, 'c')

6.3.2.4. دستور زبان رسمی اشتراک

subscription:     primary '[' subscript ']'
subscript:        single_subscript | tuple_subscript
single_subscript: proper_slice | assignment_expression
proper_slice:     [expression] ":" [expression] [ ":" [expression] ]
tuple_subscript:  ','.(single_subscript | starred_expression)+ [',']

به یاد داشته باشید که عملگر | بیانگر انتخاب ترتیبی است. به‌طور مشخص، در subscript، اگر هر دو جایگزین تطابق یابند، نخستین (single_subscript) اولویت دارد.

6.3.3. فراخوانی‌ها

یک فراخوانی، یک شیء فراخوانی‌پذیر (برای مثال، یک تابع) را با دنباله‌ای از آرگومان‌ها که ممکن است خالی باشد فراخوانی می‌کند:

call:                 primary "(" [argument_list [","] | comprehension] ")"
argument_list:        positional_arguments ["," starred_and_keywords]
                        ["," keywords_arguments]
                      | starred_and_keywords ["," keywords_arguments]
                      | keywords_arguments
positional_arguments: positional_item ("," positional_item)*
positional_item:      assignment_expression | "*" expression
starred_and_keywords: ("*" expression | keyword_item)
                      ("," "*" expression | "," keyword_item)*
keywords_arguments:   (keyword_item | "**" expression)
                      ("," keyword_item | "," "**" expression)*
keyword_item:         identifier "=" expression

ممکن است یک ویرگول پایانی اختیاری پس از آرگومان‌های جایگاهی و کلیدواژه‌ای وجود داشته باشد، اما بر معناشناسی تأثیری نمی‌گذارد.

عبارت اصلی باید به یک شیء فراخوانی‌پذیر ارزیابی شود (توابع تعریف‌شده توسط کاربر، توابع توکار، متدهای اشیاء توکار، اشیاء کلاس، متدهای نمونه‌های کلاس، و همه اشیایی که متد __call__() دارند، فراخوانی‌پذیر هستند). تمام عبارت‌های آرگومان پیش از تلاش برای فراخوانی ارزیابی می‌شوند. برای سینتکس فهرست‌های پارامتر صوری، به بخش تابع مراجعه کنید.

اگر آرگومان‌های کلیدواژه‌ای وجود داشته باشند، آن‌ها ابتدا به آرگومان‌های جایگاهی تبدیل می‌شوند، به شرح زیر. نخست، فهرستی از جایگاه‌های پر نشده برای پارامترهای صوری ایجاد می‌شود. اگر N آرگومان جایگاهی وجود داشته باشد، آن‌ها در N جایگاه نخست قرار می‌گیرند. سپس، برای هر آرگومان کلیدواژه‌ای، از شناسه برای تعیین جایگاه متناظر استفاده می‌شود (اگر شناسه با نام نخستین پارامتر صوری یکسان باشد، نخستین جایگاه استفاده می‌شود، و به همین ترتیب). اگر جایگاه از قبل پر شده باشد، استثنای TypeError پرتاب می‌شود. در غیر این صورت، آرگومان در جایگاه قرار می‌گیرد و آن را پر می‌کند (حتی اگر عبارت None باشد، جایگاه را پر می‌کند). هنگامی که همه‌ی آرگومان‌ها پردازش شدند، جایگاه‌هایی که هنوز پر نشده‌اند با مقدار پیش‌فرض متناظر از تعریف تابع پر می‌شوند. (مقادیر پیش‌فرض یک بار، هنگام تعریف تابع محاسبه می‌شوند؛ بنابراین، یک شیء تغییرپذیر مانند فهرست یا دیکشنری که به‌عنوان مقدار پیش‌فرض استفاده شود، بین همه‌ی فراخوانی‌هایی که برای جایگاه متناظر مقدار آرگومان مشخص نمی‌کنند، مشترک خواهد بود؛ معمولاً باید از این کار اجتناب شود.) اگر جایگاه‌های پر نشده‌ای وجود داشته باشند که هیچ مقدار پیش‌فرضی برای آن‌ها مشخص نشده باشد، استثنای TypeError پرتاب می‌شود. در غیر این صورت، فهرست جایگاه‌های پر شده به‌عنوان فهرست آرگومان‌ها برای فراخوانی استفاده می‌شود.

یک پیاده‌سازی ممکن است توابع توکاری را ارائه دهد که پارامترهای جایگاهی آن‌ها نام ندارند، حتی اگر برای اهداف مستندسازی «نام‌گذاری‌شده» باشند، و بنابراین نمی‌توان آن‌ها را با کلیدواژه ارسال کرد. در CPython، این حالت برای توابعی صدق می‌کند که در C پیاده‌سازی شده‌اند و از PyArg_ParseTuple() برای تجزیه آرگومان‌های خود استفاده می‌کنند.

اگر آرگومان‌های جایگاهی بیشتری نسبت به جایگاه‌های پارامتر صوری وجود داشته باشد، استثنای TypeError پرتاب می‌شود، مگر اینکه یک پارامتر صوری با استفاده از سینتکس *identifier وجود داشته باشد؛ در این حالت، آن پارامتر صوری یک تاپل شامل آرگومان‌های جایگاهی مازاد را دریافت می‌کند (یا یک تاپل خالی اگر هیچ آرگومان جایگاهی مازادی وجود نداشته باشد).

اگر آرگومان کلیدواژه‌ای وجود داشته باشد که با نام یک پارامتر صوری مطابقت نداشته باشد، یک استثنای TypeError پرتاب می‌شود، مگر اینکه یک پارامتر صوری با استفاده از سینتکس **identifier وجود داشته باشد؛ در این حالت، آن پارامتر صوری یک دیکشنری حاوی آرگومان‌های کلیدواژه‌ای اضافی دریافت می‌کند (با استفاده از کلیدواژه‌ها به‌عنوان کلیدها و مقادیر آرگومان‌ها به‌عنوان مقادیر متناظر)، یا اگر آرگومان کلیدواژه‌ای اضافی وجود نداشته باشد، یک دیکشنری خالی (جدید) دریافت می‌کند.

اگر سینتکس *expression در فراخوانی تابع آمده باشد، expression باید به یک پیمایش‌پذیر ارزیابی شود. با عناصر این پیمایش‌پذیرها چنان رفتار می‌شود که گویی آرگومان‌های جایگاهی اضافی هستند. برای فراخوانی f(x1, x2, *y, x3, x4)، اگر y به یک دنباله y1، ...، yM ارزیابی شود، این معادل یک فراخوانی با M+۴ آرگومان جایگاهی x1، x2، y1، ...، yM، x3، x4 است.

پیامد این موضوع آن است که اگرچه سینتکس *expression ممکن است بعد از آرگومان‌های کلیدواژه‌ای صریح ظاهر شود، اما قبل از آرگومان‌های کلیدواژه‌ای (و هر آرگومان **expression — در زیر ببینید) پردازش می‌شود. بنابراین:

>>> def f(a, b):
...     print(a, b)
...
>>> f(b=1, *(2,))
2 1
>>> f(a=1, *(2,))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for keyword argument 'a'
>>> f(1, *(2,))
1 2

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

اگر سینتکس **expression در فراخوانی تابع وجود داشته باشد، expression باید به یک نگاشت ارزیابی شود؛ محتوای آن به‌عنوان آرگومان‌های کلیدواژه‌ای اضافی در نظر گرفته می‌شود. اگر به پارامتری که با یک کلید مطابقت دارد، از قبل مقداری داده شده باشد (با یک آرگومان کلیدواژه‌ای صریح، یا از واگشایی دیگری)، استثنای TypeError پرتاب می‌شود.

هنگامی که از **expression استفاده می‌شود، هر کلید در این نگاشت باید یک رشته باشد. هر مقدار از این نگاشت به اولین پارامتر رسمی واجد شرایط برای انتساب کلیدواژه‌ای که نام آن برابر با کلید است، اختصاص می‌یابد. کلید لازم نیست یک شناسه پایتون باشد (برای مثال "max-temp °F" قابل قبول است، اگرچه با هیچ پارامتر رسمی‌ای که بتوان آن را اعلان کرد مطابقت نخواهد داشت). اگر هیچ مطابقتی با یک پارامتر رسمی وجود نداشته باشد، جفت کلید-مقدار توسط پارامتر ** جمع‌آوری می‌شود، در صورتی که چنین پارامتری وجود داشته باشد، و در غیر این صورت، استثنای TypeError پرتاب می‌شود.

نمی‌توان از پارامترهای صوری با سینتکس *identifier یا **identifier به‌عنوان جایگاه‌های آرگومان‌های جایگاهی یا نام‌های آرگومان‌های کلیدواژه‌ای استفاده کرد.

تغییر یافته در نسخه‌ی 3.5: فراخوانی‌های تابع هر تعداد واگشایی * و ** را می‌پذیرند، آرگومان‌های جایگاهی می‌توانند پس از واگشایی‌های پیمایش‌پذیر (*) بیایند، و آرگومان‌های کلیدواژه‌ای می‌توانند پس از واگشایی‌های دیکشنری (**) بیایند. در ابتدا توسط PEP 448 پیشنهاد شد.

یک فراخوانی همیشه مقداری را برمی‌گرداند، که ممکن است None باشد، مگر آنکه استثنایی را پرتاب کند. نحوه محاسبه این مقدار به نوع شیء فراخوانی‌پذیر بستگی دارد.

اگر این‌طور باشد---

یک تابع تعریف‌شده توسط کاربر:

بلوک کد مربوط به تابع اجرا می‌شود و فهرست آرگومان‌ها به آن داده می‌شود. نخستین کاری که بلوک کد انجام می‌دهد، مقیدسازی پارامترهای صوری به آرگومان‌ها است؛ این موضوع در بخش تابع توضیح داده شده است. هنگامی که بلوک کد یک دستور return را اجرا می‌کند، مقدار بازگشتی فراخوانی تابع را مشخص می‌کند. اگر اجرا به انتهای بلوک کد برسد بدون آنکه دستور return اجرا شود، مقدار بازگشتی None است.

یک تابع یا متد توکار:

نتیجه به مفسر بستگی دارد؛ برای توضیحات توابع و متدهای توکار به توابع توکار مراجعه کنید.

یک شیء کلاس:

یک نمونه جدید از آن کلاس بازگردانده می‌شود.

یک متد نمونه‌ی کلاس:

تابع تعریف‌شده توسط کاربر متناظر فراخوانی می‌شود، با فهرست آرگومانی که یک آیتم بیشتر از فهرست آرگومان‌های فراخوانی دارد: نمونه اولین آرگومان می‌شود.

یک نمونه از کلاس:

کلاس باید یک متد __call__() تعریف کند؛ در این صورت اثر آن همانند حالتی است که گویی آن متد فراخوانی‌شده باشد.

6.4. عبارت await

اجرای هم‌روال را بر روی یک شیء awaitable معلق می‌کند. فقط می‌تواند درون یک تابع هم‌روال استفاده شود.

await_expr: "await" primary

اضافه شده در نسخه‌ی 3.5.

6.5. عملگر توان

عملگر توان نسبت به عملگرهای یک‌عملوندی در سمت چپ خود، اولویت بیشتری دارد؛ این عملگر نسبت به عملگرهای یک‌عملوندی در سمت راست خود، اولویت کمتری دارد. سینتکس به این صورت است:

power: (await_expr | primary) ["**" u_expr]

بنابراین، در یک دنباله بدون پرانتز از عملگرهای توان و یک‌عملوندی، عملگرها از راست به چپ ارزیابی می‌شوند (این موضوع ترتیب ارزیابی عملوندها را محدود نمی‌کند): -1**2 برابر با -1 می‌شود.

عملگر توان همان معنایی را دارد که تابع توکار pow() هنگام فراخوانی با دو آرگومان دارد: این عملگر، آرگومان چپ خود را به توان آرگومان راست خود برمی‌گرداند. آرگومان‌های عددی ابتدا به یک نوع مشترک تبدیل می‌شوند، و نتیجه از آن نوع است.

برای عملوندهای int، نتیجه هم‌نوع با عملوندها است، مگر اینکه آرگومان دوم منفی باشد؛ در آن صورت، تمام آرگومان‌ها به float تبدیل می‌شوند و نتیجه‌ای از نوع float برگردانده می‌شود. برای مثال، 10**2 مقدار 100 را برمی‌گرداند، اما 10**-2 مقدار 0.01 را برمی‌گرداند.

رساندن 0.0 به توان منفی منجر به ZeroDivisionError می‌شود. رساندن یک عدد منفی به توان کسری منجر به یک عدد complex می‌شود. (در نسخه‌های پیشین، ValueError پرتاب می‌شد.)

این عملیات را می‌توان با استفاده از متدهای ویژه‌ی __pow__() و __rpow__() سفارشی کرد.

6.6. عملیات حسابی و بیتی یک‌عملوندی

تمام عملیات حسابی و بیتی یک‌عملوندی اولویت یکسانی دارند:

u_expr: power | "-" u_expr | "+" u_expr | "~" u_expr

عملگر یک‌عملوندی - (منفی)، منفیِ آرگومان عددی خود را برمی‌گرداند؛ این عملیات را می‌توان با متد ویژه __neg__() بازنویسی کرد.

عملگر یک‌عملوندی + (مثبت) آرگومان عددی خود را بدون تغییر برمی‌گرداند؛ این عملیات را می‌توان با متد ویژه __pos__() بازنویسی کرد.

عملگر یک‌عملوندی ~ (وارون‌سازی) وارونگی بیتی آرگومان عدد صحیح خود را حاصل می‌کند. وارونگی بیتی x به صورت -(x+1) تعریف شده است. این عملگر فقط بر اعداد صحیح یا اشیاء سفارشی‌ای اعمال می‌شود که متد ویژه __invert__() را بازنویسی کرده‌اند.

در هر سه حالت، اگر آرگومان نوع مناسب نداشته باشد، استثنای TypeError پرتاب می‌شود.

6.7. عملیات حسابی دودویی

عملیات حسابی دودویی دارای سطوح اولویت مرسوم هستند. توجه داشته باشید که برخی از این عملیات بر برخی انواع غیرعددی نیز اعمال می‌شوند. به جز عملگر توان، تنها دو سطح وجود دارد، یکی برای عملگرهای ضربی و دیگری برای عملگرهای جمعی:

m_expr: u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
        m_expr "//" u_expr | m_expr "/" u_expr |
        m_expr "%" u_expr
a_expr: m_expr | a_expr "+" m_expr | a_expr "-" m_expr

عملگر * (ضرب) حاصل‌ضرب آرگومان‌هایش را به دست می‌دهد. آرگومان‌ها باید یا هر دو عدد باشند، یا یکی از آرگومان‌ها باید عدد صحیح و دیگری باید یک دنباله باشد. در حالت اول، اعداد به یک نوع حقیقی مشترک تبدیل می‌شوند و سپس در هم ضرب می‌شوند. در حالت دوم، تکرار دنباله انجام می‌شود؛ ضریب تکرار منفی، یک دنباله خالی به دست می‌دهد.

این عملیات را می‌توان با استفاده از متدهای ویژه‌ی __mul__() و __rmul__() سفارشی‌سازی کرد.

تغییر یافته در نسخه‌ی 3.14: اگر تنها یکی از عملوندها یک عدد مختلط باشد، عملوند دیگر به یک عدد ممیز شناور تبدیل می‌شود.

عملگر @ (at) برای ضرب ماتریسی در نظر گرفته شده است. هیچ‌یک از انواع توکار پایتون این عملگر را پیاده‌سازی نمی‌کنند.

این عملیات را می‌توان با استفاده از متدهای ویژه __matmul__() و __rmatmul__() سفارشی‌سازی کرد.

اضافه شده در نسخه‌ی 3.5.

عملگرهای / (تقسیم) و // (تقسیم کف) خارج‌قسمت آرگومان‌های خود را برمی‌گردانند. آرگومان‌های عددی ابتدا به یک نوع مشترک تبدیل می‌شوند. تقسیم اعداد صحیح یک مقدار شناور برمی‌گرداند، در حالی که تقسیم کفِ اعداد صحیح یک عدد صحیح نتیجه می‌دهد؛ نتیجه، حاصل تقسیم ریاضی است که تابع 'floor' بر آن اعمال شده است. تقسیم بر صفر استثنای ZeroDivisionError را پرتاب می‌کند.

عملیات تقسیم را می‌توان با استفاده از متدهای ویژه __truediv__() و __rtruediv__() سفارشی‌سازی کرد. عملیات تقسیم کف را می‌توان با استفاده از متدهای ویژه __floordiv__() و __rfloordiv__() سفارشی‌سازی کرد.

عملگر % (باقی‌مانده) باقی‌مانده‌ی تقسیم آرگومان اول بر آرگومان دوم را برمی‌گرداند. آرگومان‌های عددی ابتدا به یک نوع مشترک تبدیل می‌شوند. صفر بودن آرگومان سمت راست باعث پرتاب استثنای ZeroDivisionError می‌شود. آرگومان‌ها ممکن است اعداد ممیز شناور باشند، برای مثال، 3.14%0.7 برابر 0.34 است (زیرا 3.14 برابر 4*0.7 + 0.34 است.) عملگر باقی‌مانده همیشه نتیجه‌ای با همان علامت عملوند دوم خود (یا صفر) حاصل می‌کند؛ مقدار مطلق نتیجه اکیداً کوچک‌تر از مقدار مطلق عملوند دوم است [1].

عملگرهای تقسیم کف و باقی‌مانده با اتحاد زیر به یکدیگر مرتبط هستند: x == (x//y)*y + (x%y). تقسیم کف و باقی‌مانده همچنین با تابع توکار divmod() مرتبط هستند: divmod(x, y) == (x//y, x%y). [2].

علاوه بر انجام عملیات باقی‌مانده روی اعداد، اشیاء رشته نیز عملگر % را سربارگذاری کرده‌اند تا قالب‌بندی رشته به سبک قدیمی (که به آن درون‌یابی (interpolation) نیز گفته می‌شود) انجام شود. سینتکس قالب‌بندی رشته در مرجع کتابخانه پایتون، بخش قالب‌بندی رشته به‌سبک printf توضیح داده شده است.

عملیات باقی‌مانده را می‌توان با استفاده از متدهای ویژه __mod__() و __rmod__() سفارشی‌سازی کرد.

عملگر تقسیم کف، عملگر باقی‌مانده (modulo)، و تابع divmod() برای اعداد مختلط تعریف نشده‌اند. در عوض، در صورت مناسب بودن، با استفاده از تابع abs() آن را به یک عدد ممیز شناور تبدیل کنید.

عملگر + (جمع) حاصل‌جمع آرگومان‌های خود را برمی‌گرداند. آرگومان‌ها باید یا هر دو عدد یا هر دو دنباله‌هایی از یک نوع باشند. در حالت اول، اعداد به یک نوع حقیقی مشترک تبدیل می‌شوند و سپس با هم جمع می‌شوند. در حالت دوم، دنباله‌ها به یکدیگر الحاق می‌شوند.

این عملیات را می‌توان با استفاده از متدهای ویژه‌ی __add__() و __radd__() سفارشی کرد.

تغییر یافته در نسخه‌ی 3.14: اگر تنها یکی از عملوندها یک عدد مختلط باشد، عملوند دیگر به یک عدد ممیز شناور تبدیل می‌شود.

عملگر - (تفریق)، تفاضل آرگومان‌های خود را برمی‌گرداند. آرگومان‌های عددی ابتدا به یک نوع حقیقی مشترک تبدیل می‌شوند.

این عملیات را می‌توان با استفاده از متدهای ویژه‌ی __sub__() و __rsub__() سفارشی‌سازی کرد.

تغییر یافته در نسخه‌ی 3.14: اگر تنها یکی از عملوندها یک عدد مختلط باشد، عملوند دیگر به یک عدد ممیز شناور تبدیل می‌شود.

6.8. عملیات جابه‌جایی

عملیات جابه‌جایی اولویت پایین‌تری نسبت به عملیات حسابی دارند:

shift_expr: a_expr | shift_expr ("<<" | ">>") a_expr

این عملگرها، اعداد صحیح را به‌عنوان آرگومان می‌پذیرند. آن‌ها آرگومان اول را به تعداد بیت‌های تعیین‌شده توسط آرگومان دوم، به چپ یا راست شیفت می‌دهند.

عملیات شیفت چپ را می‌توان با استفاده از متدهای ویژه __lshift__() و __rlshift__() سفارشی‌سازی کرد. عملیات شیفت راست را می‌توان با استفاده از متدهای ویژه __rshift__() و __rrshift__() سفارشی‌سازی کرد.

شیفت راست به اندازه‌ی n بیت به‌صورت تقسیم کف بر pow(2,n) تعریف می‌شود. شیفت چپ به اندازه‌ی n بیت به‌صورت ضرب در pow(2,n) تعریف می‌شود.

6.9. عملیات بیت‌به‌بیت دودویی

هر یک از سه عملیات بیتی، سطح اولویت متفاوتی دارد:

and_expr: shift_expr | and_expr "&" shift_expr
xor_expr: and_expr | xor_expr "^" and_expr
or_expr:  xor_expr | or_expr "|" xor_expr

عملگر & حاصل AND بیت‌به‌بیت آرگومان‌هایش را برمی‌گرداند، که باید اعداد صحیح باشند یا یکی از آن‌ها باید یک شیء سفارشی باشد که متدهای ویژه __and__() یا __rand__() را بازنویسی می‌کند.

عملگر ^ حاصل XOR بیتی (یا انحصاری) آرگومان‌های خود را برمی‌گرداند؛ این آرگومان‌ها باید عدد صحیح باشند یا یکی از آن‌ها باید یک شیء سفارشی باشد که متدهای ویژه‌ی __xor__() یا __rxor__() را بازنویسی کرده باشد.

عملگر | حاصل OR بیتی (شمولی) آرگومان‌هایش را برمی‌گرداند؛ آرگومان‌ها باید عدد صحیح باشند یا یکی از آن‌ها باید یک شیء سفارشی باشد که متدهای ویژه‌ی __or__() یا __ror__() را بازنویسی می‌کند.

6.10. مقایسه‌ها

برخلاف C، تمام عملیات مقایسه‌ای در پایتون اولویت یکسانی دارند که از اولویت هر عملیات حسابی، جابه‌جایی یا عملیات بیت‌به‌بیتی پایین‌تر است. همچنین برخلاف C، عبارت‌هایی مانند a < b < c تفسیری دارند که در ریاضیات مرسوم است:

comparison:    or_expr (comp_operator or_expr)*
comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!="
               | "is" ["not"] | ["not"] "in"

مقایسه‌ها مقادیر بولی را حاصل می‌کنند: True یا False. ممکن است متدهای مقایسه غنی (rich comparison methods) سفارشی، مقادیر غیربولی برگردانند. در این صورت، پایتون در زمینه‌های بولی، bool() را روی چنین مقداری فراخوانی می‌کند.

می‌توان مقایسه‌ها را به‌صورت دلخواه زنجیره‌ای کرد، برای مثال x < y <= z معادل x < y and y <= z است، با این تفاوت که y تنها یک بار ارزیابی می‌شود (اما در هر دو حالت، وقتی x < y نادرست باشد، z اصلاً ارزیابی نمی‌شود).

به‌طور رسمی، اگر a، b، c، ...، y، z عبارت باشند و op1، op2، ...، opN عملگرهای مقایسه باشند، آنگاه a op1 b op2 c ... y opN z معادل a op1 b and b op2 c and ... y opN z است، با این تفاوت که هر عبارت حداکثر یک‌بار ارزیابی می‌شود.

توجه داشته باشید که a op1 b op2 c به معنای هیچ‌گونه مقایسه‌ای بین a و c نیست، بنابراین، به‌عنوان مثال، x < y > z کاملاً مجاز است (هرچند شاید زیبا نباشد).

6.10.1. مقایسه‌های مقدار

عملگرهای <، >، ==، >=، <= و != مقادیر دو شیء را مقایسه می‌کنند. لازم نیست این دو شیء نوع یکسانی داشته باشند.

فصل اشیاء، مقادیر و انواع بیان می‌کند که اشیاء دارای یک مقدار هستند (علاوه بر نوع و هویت). مقدار یک شیء در پایتون مفهومی نسبتاً انتزاعی است: برای مثال، هیچ روش دسترسی کانونیکالی برای مقدار یک شیء وجود ندارد. همچنین الزامی وجود ندارد که مقدار یک شیء به شکل خاصی ساخته شود، مثلاً از تمام ویژگی‌های داده‌ای آن تشکیل شده باشد. عملگرهای مقایسه‌ای مفهوم خاصی از اینکه مقدار یک شیء چیست را پیاده‌سازی می‌کنند. می‌توان آن‌ها را به‌عنوان تعریف‌کننده‌ی مقدار یک شیء به‌صورت غیرمستقیم، از طریق پیاده‌سازی مقایسه‌ی خود در نظر گرفت.

از آنجا که همه انواع (مستقیم یا غیرمستقیم) زیرنوع‌هایی از object هستند، رفتار مقایسه پیش‌فرض را از object به ارث می‌برند. انواع می‌توانند رفتار مقایسه خود را با پیاده‌سازی متدهای مقایسه غنی (rich comparison methods) مانند __lt__() سفارشی‌سازی کنند، همان‌طور که در سفارشی‌سازی پایه توضیح داده شده است.

رفتار پیش‌فرض برای مقایسه برابری (== و !=) بر اساس هویت اشیء است. بنابراین، مقایسه برابری نمونه‌هایی با هویت یکسان منجر به برابری می‌شود، و مقایسه برابری نمونه‌هایی با هویت‌های متفاوت منجر به نابرابری می‌شود. انگیزه این رفتار پیش‌فرض، این خواست است که همه اشیء باید بازتابی باشند (یعنی x is y دلالت بر x == y دارد).

مقایسه ترتیبی پیش‌فرض (<، >، <= و >=) ارائه نمی‌شود؛ تلاش برای آن باعث پرتاب TypeError می‌شود. انگیزه‌ای برای این رفتار پیش‌فرض، نبود یک ناوردا مشابه با برابری است.

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

فهرست زیر رفتار مقایسه‌ای مهم‌ترین انواع توکار را توضیح می‌دهد.

  • اعداد انواع عددی توکار (انواع عددی --- int، float، complex) و انواع کتابخانه استاندارد fractions.Fraction و decimal.Decimal را می‌توان در داخل یک نوع و بین انواع مختلف مقایسه کرد، با این محدودیت که اعداد مختلط از مقایسه ترتیبی پشتیبانی نمی‌کنند. در محدوده انواع درگیر، این اعداد از نظر ریاضی (الگوریتمی) به‌درستی و بدون از دست رفتن دقت مقایسه می‌شوند.

    مقادیر غیرعدد (not-a-number) یعنی float('NaN') و decimal.Decimal('NaN') خاص هستند. هر مقایسه ترتیبی یک عدد با یک مقدار غیرعدد، نادرست است. یک پیامد غیرشهودی این است که مقادیر غیرعدد با خودشان برابر نیستند. برای مثال، اگر x = float('NaN') باشد، 3 < x، x < 3 و x == x همگی نادرست هستند، در حالی که x != x درست است. این رفتار با IEEE 754 سازگار است.

  • None و NotImplemented تک‌نمونه هستند. PEP 8 توصیه می‌کند که مقایسه برای تک‌نمونه‌ها باید همیشه با is یا is not انجام شود و هرگز از عملگرهای برابری استفاده نشود.

  • دنباله‌های دودویی (نمونه‌های bytes یا bytearray) را می‌توان درون نوعشان و بین انواعشان مقایسه کرد. این دنباله‌ها با استفاده از مقادیر عددی عناصرشان به‌صورت واژه‌نامه‌ای مقایسه می‌شوند.

  • رشته‌ها (نمونه‌های str) با استفاده از نقاط کد عددی یونیکدِ نویسه‌هایشان (نتیجه‌ی تابع توکار ord()) به‌صورت واژگانی مقایسه می‌شوند. [3]

    رشته‌ها و دنباله‌های دودویی را نمی‌توان به‌صورت مستقیم مقایسه کرد.

  • دنباله‌ها (نمونه‌هایی از tuple، list یا range) فقط می‌توانند در محدوده هر یک از نوع‌های خودشان مقایسه شوند، با این محدودیت که بازه‌ها از مقایسه ترتیبی پشتیبانی نمی‌کنند. مقایسه برابری میان این نوع‌ها منجر به نابرابری می‌شود و مقایسه ترتیبی میان این نوع‌ها TypeError را پرتاب می‌کند.

    دنباله‌ها به‌صورت لغت‌نامه‌ای با مقایسه‌ی عناصر متناظر مقایسه می‌شوند. ظروف توکار معمولاً فرض می‌کنند اشیاء یکسان با خودشان برابر هستند. این امر به آن‌ها اجازه می‌دهد آزمون‌های برابری برای اشیاء یکسان را دور بزنند تا کارایی بهبود یابد و ناورداهای داخلی خود را حفظ کنند.

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

    • برای این که دو مجموعه برابر مقایسه شوند، باید از یک نوع باشند، طول یکسانی داشته باشند، و هر جفت از عناصر متناظر باید با هم برابر باشند (برای مثال، [1,2] == (1,2) نادرست است زیرا نوع آن‌ها یکسان نیست).

    • مجموعه‌هایی که از مقایسه‌ی ترتیبی پشتیبانی می‌کنند، به همان ترتیب اولین عنصر نابرااسلایسان مرتب می‌شوند (برای مثال، [1,2,x] <= [1,2,y] همان مقدار x <= y را دارد). اگر عنصر متناظر وجود نداشته باشد، مجموعه‌ی کوتاه‌تر در ترتیب مقدم است (برای مثال، [1,2] < [1,2,3] درست است).

  • نگاشت‌ها (نمونه‌های dict) اگر و فقط اگر جفت‌های (key, value) برابر داشته باشند، برابر مقایسه می‌شوند. مقایسه‌ی برابری کلیدها و مقدارها، بازتابی‌بودن را الزامی می‌کند.

    مقایسه‌های ترتیبی (<، >، <= و >=) استثنای TypeError را پرتاب می‌کنند.

  • مجموعه‌ها (نمونه‌هایی از set یا frozenset) را می‌توان در درون نوع خود و میان نوع‌هایشان مقایسه کرد.

    آن‌ها عملگرهای مقایسه‌ای ترتیبی را به‌معنای آزمون‌های زیرمجموعه و ابرمجموعه تعریف می‌کنند. این روابط ترتیب‌های کامل را تعریف نمی‌کنند (برای مثال، دو مجموعه‌ی {1,2} و {2,3} نه برابرند، نه زیرمجموعه‌ی یکدیگرند و نه ابرمجموعه‌ی یکدیگرند). بر همین اساس، مجموعه‌ها آرگومان‌های مناسبی برای توابعی که به ترتیب کامل وابسته‌اند نیستند (برای مثال، min()، max() و sorted() در صورت دریافت فهرستی از مجموعه‌ها به‌عنوان ورودی، نتایج تعریف‌نشده تولید می‌کنند).

    مقایسه‌ی مجموعه‌ها، خاصیت بازتابی عناصر آن‌ها را اعمال می‌کند.

  • بیشتر انواع توکار دیگر متدهای مقایسه‌ای پیاده‌سازی‌شده ندارند، بنابراین رفتار مقایسه‌ای پیش‌فرض را به ارث می‌برند.

کلاس‌های تعریف‌شده توسط کاربر که رفتار مقایسه‌ی خود را سفارشی‌سازی می‌کنند، باید در صورت امکان برخی قواعد سازگاری را رعایت کنند:

  • مقایسه برابری باید بازتابی باشد. به عبارت دیگر، اشیاء یکسان باید در مقایسه برابر باشند:

    x is y دلالت بر x == y دارد

  • مقایسه باید متقارن باشد. به عبارت دیگر، عبارت‌های زیر باید نتیجه‌ی یکسانی داشته باشند:

    x == y و y == x

    x != y و y != x

    x < y و y > x

    x <= y و y >= x

  • مقایسه باید ترایا باشد. مثال‌های زیر (غیرجامع) این موضوع را نشان می‌دهند:

    x > y and y > z دلالت بر x > z دارد

    x < y and y <= z دلالت بر x < z دارد

  • مقایسه معکوس باید منجر به نقض بولی شود. به عبارت دیگر، عبارت‌های زیر باید نتیجه یکسانی داشته باشند:

    x == y و not x != y

    x < y و not x >= y (برای ترتیب کامل)

    x > y و not x <= y (برای ترتیب کامل)

    دو عبارت آخر در مورد مجموعه‌های کاملاً مرتب صدق می‌کنند (برای مثال برای دنباله‌ها، اما نه برای مجموعه‌ها یا نگاشت‌ها). همچنین دکوراتور @total_ordering را ببینید.

  • نتیجه‌ی hash() باید با برابری سازگار باشد. اشیایی که برابر هستند باید یا مقدار هش یکسانی داشته باشند، یا به‌عنوان هش‌ناپذیر (unhashable) علامت‌گذاری شوند.

پایتون این قوانین سازگاری را اعمال نمی‌کند. در واقع، مقدارهای غیرعدد (not-a-number) نمونه‌ای از پیروی نکردن از این قوانین هستند.

6.10.2. عملیات آزمون عضویت

عملگرهای in و not in عضویت را آزمایش می‌کنند. x in s اگر x عضوی از s باشد به‌صورت True ارزیابی می‌شود و در غیر این صورت به‌صورت False ارزیابی می‌شود. x not in s نقیض x in s را برمی‌گرداند. همه دنباله‌های توکار و انواع مجموعه‌ای، و همچنین دیکشنری، از این پشتیبانی می‌کنند؛ برای دیکشنری، in آزمایش می‌کند که دیکشنری دارای کلید داده‌شده‌ای است یا نه. برای انواع ظرف مانند فهرست، تاپل، مجموعه، frozenset، دیکشنری یا collections.deque، عبارت x in y معادل any(x is e or x == e for e in y) است.

برای انواع رشته و بایت، x in y اگر و فقط اگر x زیررشته‌ای از y باشد، True است. یک آزمون معادل y.find(x) != -1 است. رشته‌های خالی همیشه زیررشته‌ای از هر رشته دیگری در نظر گرفته می‌شوند، بنابراین "" in "abc" مقدار True را برمی‌گرداند.

برای کلاس‌های تعریف‌شده توسط کاربر که متد __contains__() را تعریف می‌کنند، اگر y.__contains__(x) یک مقدار درست برگرداند، x in y مقدار True را برمی‌گرداند و در غیر این صورت False را برمی‌گرداند.

برای کلاس‌های تعریف‌شده توسط کاربر که __contains__() را تعریف نمی‌کنند اما __iter__() را تعریف می‌کنند، x in y برابر True است اگر در حین پیمایش روی y، مقداری z تولید شود که عبارت x is z or x == z برای آن درست باشد. اگر در حین پیمایش استثنایی پرتاب شود، گویی in آن استثنا را پرتاب کرده است.

در نهایت، پروتکل پیمایش به‌سبک قدیمی آزموده می‌شود: اگر کلاسی __getitem__() را تعریف کند، x in y اگر و تنها در صورتی True است که یک اندیس عدد صحیح نامنفی i وجود داشته باشد، به‌طوری که x is y[i] or x == y[i] برقرار باشد و هیچ اندیس عدد صحیح کوچک‌تری استثنا IndexError را پرتاب نکند. (اگر هر استثنا دیگری پرتاب شود، گویی in آن استثنا را پرتاب کرده است).

عملگر not in به‌گونه‌ای تعریف شده است که مقدار درستی معکوسِ in را داشته باشد.

6.10.3. مقایسه‌های هویت

عملگرهای is و is not هویت یک شیء را می‌سنجند: x is y اگر و تنها اگر x و y یک شیء یکسان باشند، درست است. هویت یک شیء با استفاده از تابع id() تعیین می‌شود. x is not y مقدار درستی معکوس را برمی‌گرداند. [4]

6.11. عملیات بولی

or_test:  and_test | or_test "or" and_test
and_test: not_test | and_test "and" not_test
not_test: comparison | "not" not_test

در عملیات بولی، و همچنین هنگامی که عبارات در دستورهای کنترل جریان به کار می‌روند، مقادیر زیر به‌عنوان نادرست تفسیر می‌شوند: False، None، صفر عددی از تمام انواع، و رشته‌ها و ظروف خالی (شامل رشته‌ها، تاپل‌ها، فهرست‌ها، دیکشنری‌ها، مجموعه‌ها و frozensetها). تمام مقادیر دیگر به‌عنوان درست تفسیر می‌شوند. اشیای تعریف‌شده توسط کاربر می‌توانند مقدار درستی خود را با ارائه‌ی متد __bool__() سفارشی کنند.

عملگر not اگر آرگومان آن نادرست باشد، True و در غیر این صورت False برمی‌گرداند.

عبارت x and y ابتدا x را ارزیابی می‌کند؛ اگر x نادرست باشد، مقدار آن برگردانده می‌شود؛ در غیر این صورت، y ارزیابی می‌شود و مقدار حاصل برگردانده می‌شود.

عبارت x or y ابتدا x را ارزیابی می‌کند؛ اگر x درست باشد، مقدار آن برگردانده می‌شود؛ در غیر این صورت، y ارزیابی می‌شود و مقدار حاصل برگردانده می‌شود.

توجه داشته باشید که نه and و نه or مقدار و نوعی را که برمی‌گردانند به False و True محدود نمی‌کنند، بلکه آخرین آرگومان ارزیابی‌شده را برمی‌گردانند. این موضوع گاهی مفید است؛ مثلاً اگر s رشته‌ای باشد که در صورت خالی بودن باید با یک مقدار پیش‌فرض جایگزین شود، عبارت s or 'foo' مقدار دلخواه را برمی‌گرداند. از آنجا که not باید مقدار جدیدی ایجاد کند، صرف‌نظر از نوع آرگومان خود یک مقدار بولی برمی‌گرداند (برای مثال، not 'foo' به جای '' مقدار False تولید می‌کند.)

6.12. عبارات انتساب

assignment_expression: [identifier ":="] expression

یک عبارت انتساب (که گاهی به آن «عبارت نام‌دار» یا «والروس» نیز گفته می‌شود) یک expression را به یک identifier انتساب می‌دهد، و همزمان مقدار expression را نیز بازمی‌گرداند.

یکی از موارد استفاده‌ی رایج، هنگام پردازش عبارات باقاعده‌ی تطبیق‌یافته است:

if matching := pattern.search(data):
    do_something(matching)

یا، هنگام پردازش جریان پرونده به‌صورت تکه‌ای :

while chunk := file.read(9000):
    process(chunk)

عبارات مقیدسازی باید هنگامی که به‌عنوان دستورهای عبارتی استفاده می‌شوند و هنگامی که به‌عنوان زیرعبارت‌هایی در عبارت‌های اسلایس، شرطی، لامبدا، آرگومان کلیدواژه‌ای و عبارت‌های if در درک (comprehension-if) و در دستورهای assert، with و assignment به کار می‌روند، در پرانتز قرار گیرند. در هر جای دیگری که بتوان از آن‌ها استفاده کرد، نیازی به پرانتز نیست، از جمله در دستورهای if و while.

اضافه شده در نسخه‌ی 3.8: برای جزئیات بیشتر درباره‌ی عبارت‌های انتساب، PEP 572 را ببینید.

6.13. عبارات شرطی

conditional_expression: or_test ["if" or_test "else" expression]
expression:             conditional_expression | lambda_expr

یک عبارت شرطی (که گاهی به آن «عملگر سه‌تایی» گفته می‌شود) جایگزینی برای دستور if-else است. از آن‌جا که این یک عبارت است، مقداری برمی‌گرداند و می‌تواند به‌عنوان یک زیرعبارت ظاهر شود.

عبارت x if C else y ابتدا شرط، یعنی C را ارزیابی می‌کند، نه x را. اگر C درست باشد، x ارزیابی می‌شود و مقدار آن بازگردانده می‌شود؛ در غیر این صورت، y ارزیابی می‌شود و مقدار آن بازگردانده می‌شود.

برای جزئیات بیشتر درباره عبارات شرطی، PEP 308 را ببینید.

6.14. لامبداها

lambda_expr: "lambda" [parameter_list] ":" expression

عبارات لامبدا (که گاهی فرم‌های لامبدا نامیده می‌شوند) برای ایجاد توابع ناشناس استفاده می‌شوند. عبارت lambda parameters: expression یک شیء تابع حاصل می‌دهد. این شیء بی‌نام مانند یک شیء تابعی رفتار می‌کند که به این صورت تعریف شده باشد:

def <lambda>(parameters):
    return expression

برای سینتکس فهرست‌های پارامتر، بخش تابع را ببینید. توجه داشته باشید که توابع ایجادشده با عبارت‌های lambda نمی‌توانند شامل دستور یا حاشیه‌نویسی‌ها باشند.

6.15. فهرست‌های عبارت

starred_expression:       "*" or_expr | expression
flexible_expression:      assignment_expression | starred_expression
flexible_expression_list: flexible_expression ("," flexible_expression)* [","]
starred_expression_list:  starred_expression ("," starred_expression)* [","]
expression_list:          expression ("," expression)* [","]
yield_list:               expression_list | starred_expression "," [starred_expression_list]

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

ویرگول پایانی فقط برای ایجاد یک تاپل تک‌آیتمی، مانند 1, لازم است؛ در تمام موارد دیگر اختیاری است. یک عبارت بدون ویرگول پایانی، تاپل ایجاد نمی‌کند، بلکه مقدار آن عبارت را برمی‌گرداند. (برای ایجاد یک تاپل خالی، از یک جفت پرانتز خالی استفاده کنید: ().)

6.15.1. بازکردن بسته‌ی پیمایش‌پذیر

در یک فهرست عبارت یا تاپل، نمایش فهرست یا مجموعه، هر عبارتی ممکن است با یک ستاره (*) پیشوند شود. این نشان‌دهنده‌ی بازکردن پیمایش‌پذیر است.

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

اضافه شده در نسخه‌ی 3.5: واگشایی پیمایش‌پذیرها در فهرست‌های عبارت، که در ابتدا در PEP 448 پیشنهاد شد.

اضافه شده در نسخه‌ی 3.11: هر آیتم در یک فهرست عبارت می‌تواند ستاره‌دار شود. PEP 646 را ببینید.

6.16. ترتیب ارزیابی

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

در سطرهای زیر، عبارت‌ها به ترتیب حسابی پسوندهایشان ارزیابی می‌شوند:

expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2

6.17. اولویت عملگرها

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

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

عملگر

توضیح

(expressions...),

[expressions...]، {key: value...}، {expressions...}

پیوند یا عبارت داخل پرانتز، نمایش فهرست، نمایش دیکشنری، نمایش مجموعه

x[index], x[index:index] x(arguments...), x.attribute

زیرنویسی (شامل اسلایس)، فراخوانی، ارجاع به ویژگی

await x

عبارت await

**

توان‌رسانی [5]

+x, -x, ~x

مثبت، منفی، نقیض بیت‌به‌بیت

*, @, /, //, %

ضرب، ضرب ماتریسی، تقسیم، تقسیم کف، باقی‌مانده [6]

+، -

جمع و تفریق

<<, >>

شیفت‌ها

&

و بیت‌به‌بیت

^

XOR بیت‌به‌بیت

|

یای بیتی (Bitwise OR)

in, not in, is, is not, <, <=, >, >=, !=, ==

مقایسه‌ها، از جمله آزمون‌های عضویت و هویت

not x

نفی بولی

and

و بولی

or

یا بولی

if -- else

عبارت شرطی

lambda

عبارت لامبدا

:=

عبارت انتساب

پانویس‌ها