6. عبارات

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

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

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

name: othername

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

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

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

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

6.2. اتم‌ها

Atoms are the most basic elements of expressions. The simplest atoms are builtin constants, names and literals. More complex atoms are enclosed in paired delimiters:

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

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

Formally, the syntax for built-in constants is:

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. Parenthesized groups

A parenthesized group is an expression enclosed in parentheses. The group evaluates to the same value as the expression inside.

Groups are used to override or clarify operator precedence, in the same way as in math notation. For example:

>>> 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

Note that not everything in parentheses is a group. Specifically, a parenthesized group must include exactly one expression, and cannot end with a comma. See tuple displays and generator expressions for other parenthesized forms.

Formally, the syntax for groups is:

group: '(' assignment_expression ')'

6.2.5. Container displays

For constructing builtin containers (lists, sets, tuples or dictionaries), Python provides special syntax called displays. There are subtle differences between the four kinds of displays, detailed in the following sections. All displays, however, consist of comma-separated items enclosed in paired delimiters.

For example, a list display is a series of expressions enclosed in square brackets:

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

In list, tuple and dictionary (but not set) displays, the series may be empty:

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

If the series is not empty, the items may be followed by an additional comma, which has no effect:

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

توجه

The trailing comma is often used for displays that span multiple lines (using implicit line joining), so when a future programmer adds a new entry at the end, they do not need to modify an existing line:

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

At runtime, when a display is evaluated, the listed items are evaluated from left to right and placed into a new container of the appropriate type.

For tuple, list and set (but not dict) displays, any item in the display may be prefixed with an asterisk (*). This denotes iterable unpacking. At runtime, the asterisk-prefixed expression must evaluate to an iterable, whose contents are inserted into the container at the location of the unpacking. For example:

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

Dictionary displays use a similar mechanism called dictionary unpacking, denoted with a double asterisk (**). See نمایش‌های دیکشنری for details.

A more advanced form of displays are comprehensions, where items are computed via a set of looping and filtering instructions. See the Comprehensions section for details.

اضافه شده در نسخه‌ی 3.5: Iterable and dictionary unpacking in displays, originally proposed by PEP 448.

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

A list display is a possibly empty series of expressions enclosed in square brackets. For example:

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

See Container displays for general information on displays.

The formal grammar for list displays is:

list: '[' [flexible_expression_list] ']'

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

A set display is a non-empty series of expressions enclosed in curly braces. For example:

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

See Container displays for general information on displays.

There is no special syntax for the empty set. The {} literal is a dictionary display that constructs an empty dictionary. Call set() with no arguments to get an empty set.

The formal grammar for set displays is:

set: '{' flexible_expression_list '}'

6.2.5.3. Tuple displays

A tuple display is a series of expressions enclosed in parentheses. For example:

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

See Container displays for general information on displays.

To avoid ambiguity, if a tuple display has exactly one element, it requires a trailing comma. Without it, you get a parenthesized group:

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

To put it in other words, a tuple display is a parenthesized list of either:

  • two or more comma-separated expressions, or

  • zero or more expressions, each followed by a comma.

Since tuples are immutable, object identity rules for literals also apply to tuples: at runtime, two occurrences of tuples with the same values may or may not yield the same object.

توجه

Python's syntax also includes expression lists, where a comma-separated list of expressions is not enclosed in parentheses but evaluates to tuple.

In other words, when it comes to tuple syntax, the comma is more important that the use of parentheses. Only the empty tuple is spelled without a comma.

The formal grammar for tuple displays is:

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

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

A dictionary display is a possibly empty series of dict items enclosed in curly braces. Each dict item is a colon-separated pair of expressions: the key and its associated value. For example:

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

At runtime, when a dictionary comprehension is evaluated, the expressions are evaluated from left to right. Each key object is used as a key into the dictionary to store the corresponding value. This means that you can specify the same key multiple times in the comprehension, and the final dictionary's value for a given key will be the last one given. For example:

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

Instead of a key-value pair, a dict item may be an expression prefixed by a double asterisk **. This denotes dictionary unpacking. At runtime, the expression must evaluate to a mapping; each item of the mapping is added to the new dictionary. As with key-value pairs, later values replace values already set by earlier items and unpackings. This may be used to override a set of defaults:

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

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

The formal grammar for dict displays is:

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

6.2.6. Comprehensions

List, set and dictionary comprehensions are a form of container displays where items are computed via a set of looping and filtering instructions rather than listed explicitly.

In its simplest form, a comprehension consists of a single expression followed by a for clause. The for clause has the same syntax as the header of a for statement, without a trailing colon.

For example, a list of the first ten squares is:

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

At run time, a list comprehension creates a new list. The expression after in must evaluate to an iterable. For each element of this iterable, the element is bound to the for clause's target as in a for statement, then the expression before for is evaluated with the target in scope and the result is added to the new list. Thus, the example above is roughly equivalent to defining and calling the following function:

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

make_list_of_squares(range(10))

Set comprehensions work similarly. For example, here is a set of lowercase letters:

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

At run time, this corresponds roughly to calling this function:

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'])

Dictionary comprehensions start with a colon-separated key-value pair instead of an expression. For example:

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

At run time, this corresponds roughly to:

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

iterable([print, hex, any])

As in other kinds of dictionary displays, the same key may be specified multiple times. Earlier values are overwritten by ones that are evaluated later.

There are no tuple comprehensions. A similar syntax is instead used for generator expressions, from which you can construct a tuple like this:

>>> 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. Filtering in comprehensions

The for clause may be followed by an if clause with an expression.

For example, a list of names from the math module that start with f is:

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

At run time, the expression after if is evaluated before each element is added to the resulting container, and if it is false, the element is skipped. Thus, the above example roughly corresponds to defining and calling the following function:

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))

Filtering is a special case of more complex comprehensions. See the next section for a more formal description.

6.2.6.2. Complex comprehensions

Generally, a comprehension's initial for clause may be followed by zero or more additional for or if clauses. For example, here is a list of names exposed by two Python modules, filtered to only include names that start with 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']

At run time, this roughly corresponds to defining and calling:

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])

The elements of the new container are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce an element (or dictionary entry) each time the innermost block is reached.

Aside from the iterable expression in the leftmost for clause, the comprehension is executed in a separate implicitly nested scope. This ensures that names assigned to in the target list don't "leak" into the enclosing scope. For example:

>>> x = 'old value'
>>> [x**2 for x in range(10)]  # this `x` is local to the comprehension
>>> x
'old value'

The iterable expression in the leftmost for clause is evaluated directly in the enclosing scope and then passed as an argument to the implicitly nested scope.

Subsequent for clauses and any filter condition in the leftmost for clause cannot be evaluated in the enclosing scope as they may depend on the values obtained from the leftmost iterable.

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

Assignment expressions are not allowed inside comprehension iterable expressions (that is, the expressions after the in keyword), nor anywhere within comprehensions that appear directly in a class definition.

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

6.2.6.3. Unpacking in comprehensions

If the expression of a list or set comprehension is starred, the result will be unpacked to produce zero or more elements.

This is often used for "flattening" lists, for example:

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

At run time, this comprehension roughly corresponds to:

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

In dict comprehensions, a double-starred expression will be evaluated and then unpacked using dictionary unpacking, inserting zero or more key/value pairs into the new dictionary. As in other kinds of dictionary displays, if the same key is specified multiple times, the associated value in the resulting dictionary will be the last one specified.

For example:

>>> 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: Unpacking in comprehensions using the * and ** operators was introduced in PEP 798.

6.2.6.4. Asynchronous comprehensions

In an async def function, an async for clause may be used to iterate over a asynchronous iterator. A comprehension in an async def function may consist of either a for or async for clause following the leading expression, may contain additional for or async for clauses, and may also use await expressions.

If a comprehension contains async for clauses, or if it contains await expressions or other asynchronous comprehensions anywhere except the iterable expression in the leftmost for clause, it is called an asynchronous comprehension. An asynchronous comprehension may suspend the execution of the coroutine function in which it appears.

اضافه شده در نسخه‌ی 3.6: Asynchronous comprehensions were introduced in PEP 530.

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

6.2.6.5. Formal grammar for comprehensions

The formal grammar for comprehensions is:

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) <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 است.

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

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

یک شیء کلاس:

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

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

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

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

کلاس باید یک متد __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 (برای ترتیب کامل)

    دو عبارت آخر در مورد مجموعه‌های کاملاً مرتب صدق می‌کنند (برای مثال برای دنباله‌ها، اما نه برای مجموعه‌ها یا نگاشت‌ها). همچنین دکوراتور @~functools.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

In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false: False, None, zero of any numeric type, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true. User-defined objects can customize their truth value by providing a __bool__() method.

عملگر 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. Iterable unpacking

In an expression list or tuple, list or set display, any expression may be prefixed with an asterisk (*). This denotes iterable unpacking.

At runtime, the asterisk-prefixed expression must evaluate to an iterable. The iterable is expanded into a sequence of items, which are included in the new tuple, list, or set, at the site of the unpacking.

اضافه شده در نسخه‌ی 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

عبارت لامبدا

:=

عبارت انتساب

پانویس‌ها