6. Εκφράσεις
************

Αυτό το κεφάλαιο εξηγεί τη σημασία των στοιχείων των εκφράσεων στην
Python.

**Syntax Notes:** In this and the following chapters, grammar notation
will be used to describe syntax, not lexical analysis.

When (one alternative of) a syntax rule has the form:

   name: othername

και δεν δίνεται σημασιολογία, η σημασιολογία αυτής της μορφής του
"name" είναι η ίδια με του "othername".


6.1. Αριθμητικές μετατροπές
===========================

When a description of an arithmetic operator below uses the phrase
"the numeric arguments are converted to a common real type", this
means that the operator implementation for built-in numeric types
works as described in the Numeric Types section of the standard
library documentation.

Some additional rules apply for certain operators and non-numeric
operands (for example, a string as a left argument to the "%"
operator). Extensions must define their own conversion behavior.


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:

* "()" (parentheses): groups, tuple displays, yield atoms, and
  generator expressions;

* "[]" (square brackets): list displays;

* "{}" (curly braces): dictionary and set displays.

Formally, the syntax for atoms is:

   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. Built-in constants
-------------------------

The keywords "True", "False", and "None" name built-in constants. The
token "..." names the "Ellipsis" constant.

Evaluation of these atoms yields the corresponding value.

Σημείωση:

  Several more built-in constants are available as global variables,
  but only the ones mentioned here are keywords. In particular, these
  names cannot be reassigned or used as attributes:

     >>> 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. Αναγνωριστικά (Ονόματα)
------------------------------

Ένα αναγνωριστικό που εμφανίζεται ως άτομο είναι ένα όνομα. Δείτε την
ενότητα Ονόματα (αναγνωριστικά και λέξεις-κλειδιά) για τον λεξικό
ορισμό και την ενότητα Ονομασία και σύνδεση για την τεκμηρίωση της
ονοματοδοσίας και της σύνδεσης.

Όταν το όνομα είναι συνδεδεμένο με ένα αντικείμενο, η αποτίμηση του
ατόμου αποδίδει αυτό το αντικείμενο. Όταν ένα όνομα δεν είναι
συνδεδεμένο, η προσπάθεια αποτίμησής του κάνει raise μια εξαίρεση
"NameError".


6.2.2.1. Παραμόρφωση ιδιωτικών ονομάτων
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Όταν ένα αναγνωριστικό που εμφανίζεται κειμενικά σε έναν ορισμό κλάσης
ξεκινά με δύο ή περισσότερους χαρακτήρες υπογράμμισης (underscore) και
δεν τελειώνει με δύο ή περισσότερες υπογραμμίσεις, θεωρείται *ιδιωτικό
όνομα* αυτής της κλάσης.

Δείτε επίσης: Οι προδιαγραφές κλάσης.

Πιο συγκεκριμένα, τα ιδιωτικά ονόματα μετασχηματίζονται σε μια
μεγαλύτερη μορφή πριν παραχθεί κώδικας για αυτά. Εάν το
μετασχηματισμένο όνομα είναι μεγαλύτερο από 255 χαρακτήρες, ενδέχεται
να συμβεί περικοπή καθορισμένη από την υλοποίηση.

Ο μετασχηματισμός είναι ανεξάρτητος από το συντακτικό πλαίσιο στο
οποίο χρησιμοποιείται το αναγνωριστικό, αλλά μόνο τα ακόλουθα ιδιωτικά
αναγνωριστικά παραμορφώνονται:

* Κάθε όνομα που χρησιμοποιείται ως όνομα μιας μεταβλητής που της
  ανατίθεται τιμή ή διαβάζεται, ή οποιοδήποτε όνομα ενός
  χαρακτηριστικού στο οποίο γίνεται πρόσβαση.

  Το χαρακτηριστικό "__name__" των ένθετων συναρτήσεων, των κλάσεων
  και των ψευδώνυμων των τύπων παρόλα αυτά δεν παραμορφώνεται.

* Το όνομα των εισαγόμενων modules, π.χ., "__spam" στο "import
  __spam". Αν το module είναι μέρος ενός πακέτου (δηλαδή, το όνομά της
  περιέχει τελεία), το όνομα *δεν* παραμορφώνεται, π.χ., το "__foo"
  στο "import __foo.bar" δεν παραμορφώνεται.

* Το όνομα ενός εισαγόμενου μέλους, π.χ., "__f" στο "from spam import
  __f".

Ο κανόνας μετασχηματισμού ορίζεται ως εξής:

* Το όνομα της κλάσης, με τις αρχικές υπογραμμίσεις αφαιρεμένες και
  μια μονή αρχική υπογράμμιση εισαγμένη, τοποθετείται μπροστά από το
  αναγνωριστικό, π.χ., το αναγνωριστικό "__spam" που εμφανίζεται σε
  μια κλάση με όνομα "Foo", "_Foo" ή "__Foo" μετασχηματίζεται σε
  "_Foo__spam".

* Αν το όνομα της κλάσης αποτελείται μόνο από υπογραμμίσεις, ο
  μετασχηματισμός είναι η ταυτότητα, π.χ., το αναγνωριστικό "__spam"
  που εμφανίζεται σε μια κλάση με όνομα "_" ή "__" παραμένει ως έχει.


6.2.3. Λεκτικές Σταθερές (Literals)
-----------------------------------

A *literal* is a textual representation of a value. Python supports
numeric, string and bytes literals. Format strings and template
strings are treated as string literals.

Numeric literals consist of a single "NUMBER" token, which names an
integer, floating-point number, or an imaginary number. See the
Αριθμητικά λεκτικά section in Lexical analysis documentation for
details.

String and bytes literals may consist of several tokens. See section
Συνένωση λεκτικών αλφαριθμητικών σταθερών for details.

Note that negative and complex numbers, like "-3" or "3+4.2j", are
syntactically not literals, but unary or binary arithmetic operations
involving the "-" or "+" operator.

Evaluation of a literal yields an object of the given type ("int",
"float", "complex", "str", "bytes", or "Template") with the given
value. The value may be approximated in the case of floating-point and
imaginary literals.

The formal grammar for literals is:

   literal: strings | NUMBER


6.2.3.1. Literals and object identity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Όλες οι λεκτικές σταθερές αντιστοιχούν σε αμετάβλητους τύπους
δεδομένων, και συνεπώς η ταυτότητα του αντικειμένου είναι λιγότερο
σημαντική από την τιμή του. Πολλαπλές αποτιμήσεις λεκτικών με την ίδια
τιμή (είτε είναι η ίδια εμφάνιση στο κείμενο του προγράμματος είτε μια
διαφορετική) μπορεί να επιστρέψουν το ίδιο αντικείμενο ή ένα
διαφορετικό αντικείμενο με την ίδια τιμή.

CPython implementation detail: For example, in CPython, *small*
integers with the same value evaluate to the same object:

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

However, large integers evaluate to different objects:

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

This behavior may change in future versions of CPython. In particular,
the boundary between "small" and "large" integers has already changed
in the past.CPython will emit a "SyntaxWarning" when you compare
literals using "is":

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

See Πότε μπορώ να βασιστώ σε δοκιμές ταυτότητας με τον τελεστή is; for
more information.

Template strings are immutable but may reference mutable objects as
"Interpolation" values. For the purposes of this section, two
t-strings have the "same value" if both their structure and the
*identity* of the values match.

**Λεπτομέρεια υλοποίησης CPython:** Currently, each evaluation of a
template string results in a different object.


6.2.3.2. Συνένωση λεκτικών αλφαριθμητικών σταθερών
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Multiple adjacent string or bytes literals, possibly using different
quoting conventions, are allowed, and their meaning is the same as
their concatenation:

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

Αυτό το χαρακτηριστικό ορίζεται σε συντακτικό επίπεδο, επομένως
λειτουργεί μόνο με λεκτικές σταθερές. Για τη συνένωση εκφράσεων
αλφαριθμητικών κατά τον χρόνο εκτέλεσης, μπορεί να χρησιμοποιηθεί ο
τελεστής '+':

   >>> greeting = "Hello"
   >>> space = " "
   >>> name = "Blaise"
   >>> print(greeting + space + name)   # όχι: print(greeting space name)
   Hello Blaise

Η συνένωση λεκτικών σταθερών μπορεί να αναμιγνύει ελεύθερα ακατέργαστα
αλφαριθμητικά, αλφαριθμητικά σε τριπλά εισαγωγικά, και μορφοποιημένα
αλφαριθμητικά. Για παράδειγμα:

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

Αυτό το χαρακτηριστικό μπορεί να χρησιμοποιηθεί για να μειωθεί ο
αριθμός των backslashes που χρειάζονται, για να διαχωριστούν
μακροσκελή αλφαριθμητικά βολικά σε πολλές γραμμές, ή ακόμα και για την
προσθήκη σχολίων σε μέρη αλφαριθμητικών. Για παράδειγμα:

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

Ωστόσο, οι λεκτικές σταθερές των bytes μπορούν να συνδυαστούν μόνο με
άλλα λεκτικές σταθερές από bytes· όχι με λεκτικές αλφαριθμητικές
σταθερές οποιουδήποτε είδους. Επίσης, οι λεκτικές σταθερές
αλφαριθμητικών προτύπων μπορούν να συνδυαστούν μόνο με άλλες λεκτικές
σταθερές αλφαριθμητικών προτύπων:

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

Added in version 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}

Added in version 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: Πριν από την Python 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}

Added in version 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.

Added in version 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. Εκφράσεις γεννήτριας
---------------------------

The syntax for *generator expressions* is the same as for list
comprehensions, except that they are enclosed in parentheses instead
of brackets. For example:

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

At runtime, a generator expression evaluates to a *generator iterator*
which yields the same values as the corresponding list comprehension:

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

Thus, the example above is roughly equivalent to defining and calling
the following generator function:

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

   make_generator_of_squares(iter(range(10)))

The enclosing parentheses can be omitted in calls when the generator
expression is the only positional argument and there are no keyword
arguments. See the Calls section for details. For example:

   # 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

The iterable expression in the leftmost "for" clause is evaluated
immediately, so that an error raised by this expression will be
emitted at the point where the generator expression is defined, rather
than at the point where the first value is retrieved:

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

After the expression is evaluated, an iterator is created from the
result, as if "iter()" was called on it. Any error raised when
creating the iterator is also emitted immediately:

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

All other expressions are evaluated lazily, in the same fashion as
normal generators (that is, when the iterator is asked to yield a
value):

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

To avoid interfering with the expected operation of the generator
expression itself, "yield" and "yield from" expressions are prohibited
inside the implicitly nested scope.

If a generator expression contains either "async for" clauses or
"await" expressions it is called an *asynchronous generator
expression*. An asynchronous generator expression returns a new
asynchronous generator object, which is an asynchronous iterator (see
Ασύγχρονοι Iterators).

The formal grammar for generator expressions is:

   generator_expression: "(" comprehension ")"

Added in version 3.6: Εισήχθησαν οι εκφράσεις ασύγχρονης γεννήτριας.

Άλλαξε στην έκδοση 3.7: Πριν από την Python 3.7, οι εκφράσεις
ασύγχρονης γεννήτριας μπορούσαν να εμφανιστούν μόνο σε "async def"
coroutines. Ξεκινώντας με την 3.7, οποιαδήποτε συνάρτηση μπορεί να
χρησιμοποιήσει εκφράσεις ασύγχρονης γεννήτριας.

Άλλαξε στην έκδοση 3.8: Τα "yield" και "yield from" απαγορεύονται στο
έμμεσα φωλιασμένο εύρος.


6.2.8. Εκφράσεις απόδοσης
-------------------------

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

Η έκφραση απόδοσης χρησιμοποιείται κατά τον ορισμό μιας συνάρτησης
*generator* ή μιας συνάρτησης *asynchronous generator* και συνεπώς
μπορεί να χρησιμοποιηθεί μόνο στο σώμα ενός ορισμού συνάρτησης. Η
χρήση μιας έκφρασης απόδοσης στο σώμα μιας συνάρτησης υποχρεώνει αυτή
τη συνάρτηση να είναι συνάρτηση γεννήτριας, και η χρήση της στο σώμα
μιας συνάρτησης "async def" υποχρεώνει αυτή τη συνάρτηση coroutine να
είναι συνάρτηση ασύγχρονης γεννήτριας. Για παράδειγμα:

   def gen():  # ορίζει μια συνάρτηση γεννήτριας
       yield 123

   async def agen(): # ορίζει μια συνάρτηση ασύγχρονης γεννήτριας
       yield 123

Λόγω των παρενεργειών τους στο περιέχον εύρος, οι εκφράσεις "yield"
δεν επιτρέπονται ως μέρος των εμμέσως ορισμένων ευρών που
χρησιμοποιούνται για την υλοποίηση συμπτύξεων και εκφράσεων
γεννήτριας.

Άλλαξε στην έκδοση 3.8: Οι εκφράσεις απόδοσης απαγορεύονται στα έμμεσα
φωλιασμένα εύρη που χρησιμοποιούνται για την υλοποίηση συμπτύξεων και
εκφράσεων γεννήτριας.

Οι συναρτήσεις γεννήτριας περιγράφονται παρακάτω, ενώ οι συναρτήσεις
ασύγχρονης γεννήτριας περιγράφονται ξεχωριστά στην ενότητα Συναρτήσεις
ασύγχρονης γεννήτριας.

Όταν καλείται μια συνάρτηση γεννήτριας, επιστρέφει έναν iterator
γνωστό ως γεννήτρια. Αυτή η γεννήτρια ελέγχει στη συνέχεια την
εκτέλεση της συνάρτησης γεννήτριας. Η εκτέλεση ξεκινά όταν καλείται
μία από τις μεθόδους της γεννήτριας. Εκείνη τη στιγμή, η εκτέλεση
προχωρά στην πρώτη έκφραση απόδοσης, όπου αναστέλλεται ξανά,
επιστρέφοντας την τιμή του "yield_list" σε αυτόν που κάλεσε τη
γεννήτρια, ή "None" αν παραλειφθεί το "yield_list". Με τον όρο
αναστέλλεται, εννοούμε ότι διατηρείται όλη η τοπική κατάσταση,
συμπεριλαμβανομένων των τρεχουσών συνδέσεων των τοπικών μεταβλητών,
του δείκτη εντολών, της εσωτερικής στοίβας αποτίμησης και της
κατάστασης οποιουδήποτε χειρισμού εξαιρέσεων. Όταν η εκτέλεση
συνεχίζεται με την κλήση μιας από τις μεθόδους της γεννήτριας, η
συνάρτηση μπορεί να προχωρήσει ακριβώς σαν η έκφραση απόδοσης να ήταν
απλώς άλλη μια εξωτερική κλήση. Η τιμή της έκφρασης απόδοσης μετά τη
συνέχιση εξαρτάται από τη μέθοδο που συνέχισε την εκτέλεση. Αν
χρησιμοποιείται η "__next__()" (συνήθως μέσω μιας "for" ή της
ενσωματωμένης "next()") τότε το αποτέλεσμα είναι "None". Διαφορετικά,
αν χρησιμοποιείται η "send()", τότε το αποτέλεσμα θα είναι η τιμή που
περάστηκε σε αυτήν τη μέθοδο.

Όλα αυτά κάνουν τις συναρτήσεις γεννήτριας αρκετά παρόμοιες με τις
coroutines· αποδίδουν πολλές φορές, έχουν περισσότερα από ένα σημεία
εισόδου και η εκτέλεσή τους μπορεί να ανασταλεί. Η μόνη διαφορά είναι
ότι μια συνάρτηση γεννήτριας δεν μπορεί να ελέγξει πού πρέπει να
συνεχιστεί η εκτέλεση αφού αποδώσει· ο έλεγχος μεταφέρεται πάντα σε
αυτόν που κάλεσε τη γεννήτρια.

Οι εκφράσεις απόδοσης επιτρέπονται οπουδήποτε σε μια δομή "try". Αν η
γεννήτρια δεν συνεχιστεί πριν οριστικοποιηθεί (φτάνοντας σε μηδενικό
αριθμό αναφορών ή συλλεγόμενη από τον συλλέκτη απορριμμάτων), θα
κληθεί η μέθοδος "close()" του επαναλήπτη - γεννήτρια, επιτρέποντας σε
τυχόν εκκρεμείς προτάσεις "finally" να εκτελεστούν.

Όταν χρησιμοποιείται το "yield from <expr>", η παρεχόμενη έκφραση
πρέπει να είναι ένα iterable. Οι τιμές που παράγονται από την
επανάληψη αυτού του iterable περνούν απευθείας σε αυτόν που καλεί τις
μεθόδους της τρέχουσας γεννήτριας. Τυχόν τιμές που περνούν με την
"send()" και τυχόν εξαιρέσεις που περνούν με την "throw()" περνούν
στον υποκείμενο iterator αν διαθέτει τις κατάλληλες μεθόδους. Αν δεν
συμβαίνει αυτό, τότε η "send()" θα κάνει raise το "AttributeError" ή
το "TypeError", ενώ η "throw()" απλώς θα κάνει raise άμεσα την
εξαίρεση που της περάστηκε.

Όταν ο υποκείμενος iterator ολοκληρωθεί, η ιδιότητα "value" του
στιγμιοτύπου "StopIteration" που κάνει raise γίνεται η τιμή της
έκφρασης yield. Μπορεί είτε να οριστεί ρητά κατά την πρόκληση της
"StopIteration", είτε αυτόματα όταν ο subiterator είναι γεννήτρια
(επιστρέφοντας μια τιμή από την υπογεννήτρια).

Άλλαξε στην έκδοση 3.3: Προστέθηκε το "yield from <expr>" για την
ανάθεση της ροής ελέγχου σε έναν subiterator.

Οι παρενθέσεις μπορούν να παραλειφθούν όταν η έκφραση απόδοσης είναι η
μοναδική έκφραση στη δεξιά πλευρά μιας πρότασης ανάθεσης.

Δείτε επίσης:

  **PEP 255** - Απλές Γεννήτριες
     Η πρόταση για την προσθήκη των γεννητριών και της πρότασης
     "yield" στην Python.

  **PEP 342** - Coroutines μέσω βελτιωμένων γεννητριών
     Η πρόταση για τη βελτίωση του API και της σύνταξης των
     γεννητριών, καθιστώντας τες χρησιμοποιήσιμες ως απλές coroutines.

  **PEP 380** - Σύνταξη για ανάθεση σε μια υπογεννήτρια
     Η πρόταση για την εισαγωγή της σύνταξης "yield_from", κάνοντας
     την ανάθεση σε υπογεννήτριες εύκολη.

  **PEP 525** - Ασύγχρονες Γεννήτριες
     Η πρόταση που επέκτεινε το **PEP 492** προσθέτοντας δυνατότητες
     γεννήτριας στις coroutine συναρτήσεις.


6.2.8.1. Μέθοδοι iterator - γεννήτριας
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Αυτή η υποενότητα περιγράφει τις μεθόδους ενός generator iterator.
Μπορούν να χρησιμοποιηθούν για τον έλεγχο της εκτέλεσης μιας
συνάρτησης γεννήτριας.

Σημειώστε ότι η κλήση οποιασδήποτε από τις παρακάτω μεθόδους
γεννήτριας όταν η γεννήτρια ήδη εκτελείται, κάνει raise μια εξαίρεση
"ValueError".

generator.__next__()

   Ξεκινά την εκτέλεση μιας συνάρτησης γεννήτριας ή τη συνεχίζει στην
   τελευταία εκτελεσθείσα έκφραση απόδοσης. Όταν μια συνάρτηση
   γεννήτριας συνεχίζεται με μια μέθοδο "__next__()", η τρέχουσα
   έκφραση απόδοσης αποτιμάται πάντα σε "None". Η εκτέλεση στη
   συνέχεια συνεχίζεται στην επόμενη έκφραση απόδοσης, όπου η
   γεννήτρια αναστέλλεται ξανά, και η τιμή του "yield_list"
   επιστρέφεται σε αυτόν που κάλεσε την "__next__()". Αν η γεννήτρια
   τερματίσει χωρίς να αποδώσει άλλη τιμή, κάνει raise μια εξαίρεση
   "StopIteration".

   Αυτή η μέθοδος συνήθως καλείται έμμεσα, π.χ. από έναν βρόχο "for",
   ή από την ενσωματωμένη συνάρτηση "next()".

generator.send(value)

   Συνεχίζει την εκτέλεση και "στέλνει" μια τιμή μέσα στη συνάρτηση
   γεννήτριας. Το όρισμα *value* γίνεται το αποτέλεσμα της τρέχουσας
   έκφρασης απόδοσης. Η μέθοδος "send()" επιστρέφει την επόμενη τιμή
   που αποδίδεται από τη γεννήτρια, ή κάνει raise το "StopIteration"
   αν η γεννήτρια τερματίσει χωρίς να αποδώσει άλλη τιμή. Όταν η
   "send()" καλείται για να ξεκινήσει τη γεννήτρια, πρέπει να κληθεί
   με όρισμα "None", επειδή δεν υπάρχει καμία έκφραση απόδοσης που θα
   μπορούσε να λάβει την τιμή.

generator.throw(value)
generator.throw(type[, value[, traceback]])

   Κάνει raise μια εξαίρεση στο σημείο όπου η γεννήτρια είχε παύσει,
   και επιστρέφει την επόμενη τιμή που αποδίδεται από τη συνάρτηση
   γεννήτριας. Αν η γεννήτρια τερματίσει χωρίς να αποδώσει άλλη τιμή,
   κάνει raise μια εξαίρεση "StopIteration". Αν η συνάρτηση γεννήτριας
   δεν πιάσει την εξαίρεση που της περάστηκε, ή αν κάνει raise μια
   διαφορετική εξαίρεση, τότε αυτή η εξαίρεση μεταβιβάζεται σε αυτόν
   που την κάλεσε.

   Σε τυπική χρήση, καλείται με ένα μόνο στιγμιότυπο εξαίρεσης,
   παρόμοια με τον τρόπο που χρησιμοποιείται η λέξη-κλειδί "raise".

   Για συμβατότητα προς τα πίσω, ωστόσο, υποστηρίζεται η δεύτερη
   υπογραφή, ακολουθώντας μια σύμβαση από παλαιότερες εκδόσεις της
   Python. Το όρισμα *type* θα πρέπει να είναι μια κλάση εξαίρεσης,
   και το *value* θα πρέπει να είναι ένα στιγμιότυπο εξαίρεσης. Αν δεν
   παρέχεται το *value*, καλείται ο κατασκευαστής του *type* για να
   ληφθεί ένα στιγμιότυπο. Αν παρέχεται το *traceback*, ορίζεται στην
   εξαίρεση, διαφορετικά οποιαδήποτε υπάρχον χαρακτηριστικό
   "__traceback__" αποθηκευμένο στο *value* μπορεί να καθαριστεί.

   Άλλαξε στην έκδοση 3.12: Η δεύτερη υπογραφή (type[, value[,
   traceback]]) έχει χαρακτηριστεί ως απαρχαιωμένη και ενδέχεται να
   αφαιρεθεί σε μελλοντική έκδοση της Python.

generator.close()

   Κάνει raise μια εξαίρεση "GeneratorExit" στο σημείο όπου η
   συνάρτηση γεννήτριας είχε παύσει (ισοδύναμο με την κλήση
   "throw(GeneratorExit)"). Η εξαίρεση γίνεται raise από την έκφραση
   απόδοσης όπου η γεννήτρια είχε παύσει. Αν η συνάρτηση γεννήτριας
   πιάσει την εξαίρεση και επιστρέψει μια τιμή, αυτή η τιμή
   επιστρέφεται από την "close()". Αν η συνάρτηση γεννήτριας είναι ήδη
   κλειστή, ή κάνει raise το "GeneratorExit" (μη πιάνοντας την
   εξαίρεση), η "close()" επιστρέφει "None". Αν η γεννήτρια αποδώσει
   μια τιμή, κάνει raise μια "RuntimeError". Αν η γεννήτρια κάνει
   raise οποιαδήποτε άλλη εξαίρεση, μεταβιβάζεται σε αυτόν που την
   κάλεσε. Αν η γεννήτρια έχει ήδη τερματίσει λόγω εξαίρεσης ή
   κανονικού τερματισμού, η "close()" επιστρέφει "None" και δεν έχει
   κανένα άλλο αποτέλεσμα.

   Άλλαξε στην έκδοση 3.13: Αν μια γεννήτρια επιστρέψει μια τιμή κατά
   το κλείσιμό της, η τιμή επιστρέφεται από την "close()".


6.2.8.2. Παραδείγματα
~~~~~~~~~~~~~~~~~~~~~

Εδώ είναι ένα απλό παράδειγμα που επιδεικνύει τη συμπεριφορά των
γεννητριών και των συναρτήσεων γεννήτριας:

   >>> 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:
Syntax for Delegating to a Subgenerator στο "What's New in Python."


6.2.8.3. Συναρτήσεις ασύγχρονης γεννήτριας
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Η παρουσία μιας έκφρασης απόδοσης σε μια συνάρτηση ή μέθοδο που
ορίζεται χρησιμοποιώντας "async def" ορίζει περαιτέρω τη συνάρτηση ως
συνάρτηση *asynchronous generator*.

Όταν καλείται μια συνάρτηση ασύγχρονης γεννήτριας, επιστρέφει έναν
ασύγχρονο iterator γνωστό ως αντικείμενο ασύγχρονης γεννήτριας. Αυτό
το αντικείμενο στη συνέχεια ελέγχει την εκτέλεση της συνάρτησης
γεννήτριας. Ένα αντικείμενο ασύγχρονης γεννήτριας χρησιμοποιείται
τυπικά σε μια πρόταση "async for" σε μια συνάρτηση coroutine, κατ'
αναλογία με τον τρόπο που θα χρησιμοποιούνταν ένα αντικείμενο
γεννήτριας σε μια πρόταση "for".

Η κλήση μίας από τις μεθόδους της ασύγχρονης γεννήτριας επιστρέφει ένα
αντικείμενο *awaitable*, και η εκτέλεση ξεκινά όταν αυτό το
αντικείμενο αναμένεται. Εκείνη τη στιγμή, η εκτέλεση προχωρά στην
πρώτη έκφραση απόδοσης, όπου αναστέλλεται ξανά, επιστρέφοντας την τιμή
του "yield_list" στην coroutine που αναμένει. Όπως και με μια
γεννήτρια, αναστολή σημαίνει ότι διατηρείται όλη η τοπική κατάσταση,
συμπεριλαμβανομένων των τρεχουσών συνδέσεων των τοπικών μεταβλητών,
του δείκτη εντολών, της εσωτερικής στοίβας αποτίμησης και της
κατάστασης οποιουδήποτε χειρισμού εξαιρέσεων. Όταν η εκτέλεση
συνεχίζεται αναμένοντας το επόμενο αντικείμενο που επιστρέφεται από
τις μεθόδους της ασύγχρονης γεννήτριας, η συνάρτηση μπορεί να
προχωρήσει ακριβώς σαν η έκφραση απόδοσης να ήταν απλώς άλλη μια
εξωτερική κλήση. Η τιμή της έκφρασης απόδοσης μετά τη συνέχιση
εξαρτάται από τη μέθοδο που συνέχισε την εκτέλεση. Αν χρησιμοποιείται
η "__anext__()" τότε το αποτέλεσμα είναι "None". Διαφορετικά, αν
χρησιμοποιείται η "asend()", τότε το αποτέλεσμα θα είναι η τιμή που
περάστηκε σε αυτήν τη μέθοδο.

Αν μια ασύγχρονη γεννήτρια τερματιστεί πρόωρα μέσω του "break", η
εργασία που την κάλεσε ακυρωθεί, ή λόγω άλλων εξαιρέσεων, ο κώδικας
ασύγχρονου καθαρισμού της γεννήτριας θα εκτελεστεί και πιθανώς θα
κάνει raise εξαιρέσεις ή θα αποκτήσει πρόσβαση σε μεταβλητές
περιβάλλοντος σε ένα μη αναμενόμενο περιβάλλον -- ίσως μετά τη
διάρκεια ζωής των εργασιών από τις οποίες εξαρτάται, ή κατά τον
τερματισμό του βρόχου συμβάντων όταν καλείται το hook συλλογής
απορριμμάτων της ασύγχρονης γεννήτριας. Για να αποφευχθεί αυτό, αυτός
που καλεί πρέπει να κλείσει ρητά την ασύγχρονη γεννήτρια καλώντας τη
μέθοδο "aclose()" για να οριστικοποιήσει τη γεννήτρια και τελικά να
την αποσυνδέσει από τον βρόχο συμβάντων.

Σε μια συνάρτηση ασύγχρονης γεννήτριας, οι εκφράσεις απόδοσης
επιτρέπονται οπουδήποτε σε μια δομή "try". Ωστόσο, αν μια ασύγχρονη
γεννήτρια δεν συνεχιστεί πριν οριστικοποιηθεί (φτάνοντας σε μηδενικό
αριθμό αναφορών ή συλλεχθεί από τον συλλέκτη απορριμμάτων), τότε μια
έκφραση απόδοσης μέσα σε μια δομή "try" θα μπορούσε να οδηγήσει σε
αποτυχία εκτέλεσης εκκρεμών προτάσεων "finally". Σε αυτή την
περίπτωση, είναι ευθύνη του βρόχου συμβάντων ή του
χρονοπρογραμματιστή, που εκτελεί την ασύγχρονη γεννήτρια, να καλέσει
τη μέθοδο "aclose()" του iterator της ασύγχρονης γεννήτριας και να
εκτελέσει το αντικείμενο coroutine που προκύπτει, επιτρέποντας έτσι σε
τυχόν εκκρεμείς προτάσεις "finally" να εκτελεστούν.

Για να φροντίσει για την οριστικοποίηση κατά τον τερματισμό του βρόχου
συμβάντων, ένας βρόχος συμβάντων θα πρέπει να ορίσει μια συνάρτηση
*finalizer* η οποία δέχεται έναν iterator ασύγχρονης γεννήτριας και
προφανώς καλεί την "aclose()" και εκτελεί την coroutine. Αυτός ο
*finalizer* μπορεί να καταχωρηθεί καλώντας την
"sys.set_asyncgen_hooks()". Κατά την πρώτη επανάληψη, ένας iterator
ασύγχρονης γεννήτριας θα αποθηκεύσει τον καταχωρημένο *finalizer* για
να κληθεί κατά την οριστικοποίηση. Για ένα παράδειγμα αναφοράς μιας
μεθόδου *finalizer* δείτε την υλοποίηση της
"asyncio.Loop.shutdown_asyncgens" στο Lib/asyncio/base_events.py.

Η έκφραση "yield from <expr>" αποτελεί συντακτικό σφάλμα όταν
χρησιμοποιείται σε μια συνάρτηση ασύγχρονης γεννήτριας.


6.2.8.4. Μέθοδοι iterator ασύγχρονης γεννήτριας
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Αυτή η υποενότητα περιγράφει τις μεθόδους ενός iterator ασύγχρονης
γεννήτριας, οι οποίες χρησιμοποιούνται για τον έλεγχο της εκτέλεσης
μιας συνάρτησης γεννήτριας.

async agen.__anext__()

   Επιστρέφει ένα awaitable το οποίο όταν εκτελεστεί ξεκινά να εκτελεί
   την ασύγχρονη γεννήτρια ή τη συνεχίζει στην τελευταία εκτελεσθείσα
   έκφραση απόδοσης. Όταν μια συνάρτηση ασύγχρονης γεννήτριας
   συνεχίζεται με μια μέθοδο "__anext__()", η τρέχουσα έκφραση
   απόδοσης αποτιμάται πάντα σε "None" στο επιστρεφόμενο awaitable, το
   οποίο όταν εκτελεστεί θα συνεχίσει στην επόμενη έκφραση απόδοσης. Η
   τιμή του "yield_list" της έκφρασης απόδοσης είναι η τιμή της
   εξαίρεσης "StopIteration" που γίνεται raise από την coroutine που
   ολοκληρώνεται. Αν η ασύγχρονη γεννήτρια τερματίσει χωρίς να
   αποδώσει άλλη τιμή, το awaitable αντίθετα κάνει raise μια εξαίρεση
   "StopAsyncIteration", σηματοδοτώντας ότι η ασύγχρονη επανάληψη έχει
   ολοκληρωθεί.

   Αυτή η μέθοδος συνήθως καλείται έμμεσα από έναν βρόχο "async for".

async agen.asend(value)

   Επιστρέφει ένα awaitable το οποίο όταν εκτελεστεί συνεχίζει την
   εκτέλεση της ασύγχρονης γεννήτριας. Όπως και με τη μέθοδο "send()"
   για μια γεννήτρια, αυτό "στέλνει" μια τιμή μέσα στη συνάρτηση
   ασύγχρονης γεννήτριας, και το όρισμα *value* γίνεται το αποτέλεσμα
   της τρέχουσας έκφρασης απόδοσης. Το awaitable που επιστρέφεται από
   τη μέθοδο "asend()" θα επιστρέψει την επόμενη τιμή που αποδίδεται
   από τη γεννήτρια ως την τιμή της "StopIteration" που γίνεται raise,
   ή κάνει raise το "StopAsyncIteration" αν η ασύγχρονη γεννήτρια
   τερματίσει χωρίς να αποδώσει άλλη τιμή. Όταν η "asend()" καλείται
   για να ξεκινήσει την ασύγχρονη γεννήτρια, πρέπει να κληθεί με
   όρισμα "None", επειδή δεν υπάρχει καμία έκφραση απόδοσης που θα
   μπορούσε να λάβει την τιμή.

async agen.athrow(value)
async agen.athrow(type[, value[, traceback]])

   Επιστρέφει ένα awaitable που κάνει raise μια εξαίρεση τύπου "type"
   στο σημείο όπου η ασύγχρονη γεννήτρια είχε παύσει, και επιστρέφει
   την επόμενη τιμή που αποδίδεται από τη συνάρτηση γεννήτριας ως την
   τιμή της εξαίρεσης "StopIteration" που γίνεται raise. Αν η
   ασύγχρονη γεννήτρια τερματίσει χωρίς να αποδώσει άλλη τιμή, γίνεται
   raise μια εξαίρεση "StopAsyncIteration" από το awaitable. Αν η
   συνάρτηση γεννήτριας δεν πιάσει την εξαίρεση που της περάστηκε, ή
   αν κάνει raise μια διαφορετική εξαίρεση, τότε όταν εκτελεστεί το
   awaitable αυτή η εξαίρεση μεταβιβάζεται σε αυτόν που κάλεσε το
   awaitable.

   Άλλαξε στην έκδοση 3.12: Η δεύτερη υπογραφή (type[, value[,
   traceback]]) έχει χαρακτηριστεί ως απαρχαιωμένη και ενδέχεται να
   αφαιρεθεί σε μελλοντική έκδοση της Python.

async agen.aclose()

   Επιστρέφει ένα awaitable που όταν εκτελεστεί θα προκαλέσει μια
   "GeneratorExit" στη συνάρτηση ασύγχρονης γεννήτριας στο σημείο όπου
   είχε παύσει. Αν η συνάρτηση ασύγχρονης γεννήτριας στη συνέχεια
   τερματιστεί ομαλά, είναι ήδη κλειστή, ή κάνει raise το
   "GeneratorExit" (μη πιάνοντας την εξαίρεση), τότε το επιστρεφόμενο
   awaitable θα κάνει raise μια εξαίρεση "StopIteration". Τυχόν
   περαιτέρω awaitables που επιστρέφονται από επόμενες κλήσεις στην
   ασύγχρονη γεννήτρια θα κάνουν raise μια εξαίρεση
   "StopAsyncIteration". Αν η ασύγχρονη γεννήτρια αποδώσει μια τιμή,
   γίνεται raise μια "RuntimeError" από το awaitable. Αν η ασύγχρονη
   γεννήτρια κάνει raise οποιαδήποτε άλλη εξαίρεση, μεταβιβάζεται σε
   αυτόν που κάλεσε το awaitable. Αν η ασύγχρονη γεννήτρια έχει ήδη
   τερματίσει λόγω εξαίρεσης ή κανονικού τερματισμού, τότε περαιτέρω
   κλήσεις στην "aclose()" θα επιστρέψουν ένα awaitable που δεν κάνει
   τίποτα.


6.3. Πρωτεύοντα
===============

Τα πρωτεύοντα αντιπροσωπεύουν τις πιο στενά συνδεδεμένες λειτουργίες
της γλώσσας. Η σύνταξή τους είναι:

   primary: atom | attributeref | subscription | call


6.3.1. Αναφορές χαρακτηριστικών
-------------------------------

Μια αναφορά χαρακτηριστικού είναι ένα πρωτεύον που ακολουθείται από
μια τελεία και ένα όνομα:

   attributeref: primary "." identifier

Το πρωτεύον πρέπει να αποτιμάται σε ένα αντικείμενο ενός τύπου που
υποστηρίζει αναφορές χαρακτηριστικών, κάτι που κάνουν τα περισσότερα
αντικείμενα. Στη συνέχεια ζητείται από αυτό το αντικείμενο να παράγει
το χαρακτηριστικό της οποίας το όνομα είναι το αναγνωριστικό. Ο τύπος
και η τιμή που παράγεται καθορίζονται από το αντικείμενο. Πολλαπλές
αποτιμήσεις της ίδιας αναφοράς χαρακτηριστικού μπορεί να αποδώσουν
διαφορετικά αντικείμενα.

Αυτή η παραγωγή μπορεί να προσαρμοστεί υπερκαλύπτοντας τη μέθοδο
"__getattribute__()" ή τη μέθοδο "__getattr__()". Η μέθοδος
"__getattribute__()" καλείται πρώτη και είτε επιστρέφει μια τιμή είτε
κάνει raise το "AttributeError", αν η ιδιότητα δεν είναι διαθέσιμη.

Αν γίνει raise το "AttributeError" και το αντικείμενο έχει μια μέθοδο
"__getattr__()", αυτή η μέθοδος καλείται ως εναλλακτική.


6.3.2. Subscriptions and slicings
---------------------------------

The *subscription* syntax is usually used for selecting an element
from a container -- for example, to get a value from a "dict":

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

In the subscription syntax, the object being subscribed -- a primary
-- is followed by a *subscript* in square brackets. In the simplest
case, the subscript is a single expression.

Depending on the type of the object being subscribed, the subscript is
sometimes called a *key* (for mappings), *index* (for sequences), or
*type argument* (for *generic types*). Syntactically, these are all
equivalent:

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

At runtime, the interpreter will evaluate the primary and the
subscript, and call the primary's "__getitem__()" or
"__class_getitem__()" *special method* with the subscript as argument.
For more details on which of these methods is called, see
__class_getitem__ έναντι __getitem__.

To show how subscription works, we can define a custom object that
implements "__getitem__()" and prints out the value of the subscript:

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

See "__getitem__()" documentation for how built-in types handle
subscription.

Subscriptions may also be used as targets in assignment or deletion
statements. In these cases, the interpreter will call the subscripted
object's "__setitem__()" or "__delitem__()" *special method*,
respectively, instead of "__getitem__()".

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

All advanced forms of *subscript* documented in the following sections
are also usable for assignment and deletion.


6.3.2.1. Τεμαχισμοί
~~~~~~~~~~~~~~~~~~~

A more advanced form of subscription, *slicing*, is commonly used to
extract a portion of a sequence. In this form, the subscript is a
*slice*: up to three expressions separated by colons. Any of the
expressions may be omitted, but a slice must contain at least one
colon:

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

When a slice is evaluated, the interpreter constructs a "slice" object
whose "start", "stop" and "step" attributes, respectively, are the
results of the expressions between the colons. Any missing expression
evaluates to "None". This "slice" object is then passed to the
"__getitem__()" or "__class_getitem__()" *special method*, as above.

   # 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. Comma-separated subscripts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The subscript can also be given as two or more comma-separated
expressions or slices:

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

This form is commonly used with numerical libraries for slicing multi-
dimensional data. In this case, the interpreter constructs a "tuple"
of the results of the expressions or slices, and passes this tuple to
the "__getitem__()" or "__class_getitem__()" *special method*, as
above.

The subscript may also be given as a single expression or slice
followed by a comma, to specify a one-element tuple:

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


6.3.2.3. "Starred" subscriptions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Added in version 3.11: Expressions in *tuple_slices* may be starred.
See **PEP 646**.

The subscript can also contain a starred expression. In this case, the
interpreter unpacks the result into a tuple, and passes this tuple to
"__getitem__()" or "__class_getitem__()":

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

Starred expressions may be combined with comma-separated expressions
and slices:

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


6.3.2.4. Formal subscription grammar
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   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)+ [',']

Recall that the "|" operator denotes ordered choice. Specifically, in
"subscript", if both alternatives would match, the first
("single_subscript") has priority.


6.3.3. Κλήσεις
--------------

Μια κλήση καλεί ένα καλέσιμο αντικείμενο (π.χ., ένα *function*) με μια
πιθανώς κενή σειρά *ορισμάτων*:

   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__()" είναι καλέσιμα). Όλες οι εκφράσεις ορισμάτων αποτιμώνται
πριν επιχειρηθεί η κλήση. Παρακαλώ ανατρέξτε στην ενότητα Ορισμοί
συναρτήσεων για τη σύνταξη των τυπικών λιστών *parameter*.

Αν υπάρχουν ορίσματα λέξης-κλειδιού, μετατρέπονται πρώτα σε ορίσματα
θέσης, ως εξής. Αρχικά, δημιουργείται μια λίστα από μη συμπληρωμένες
θέσεις για τις τυπικές παραμέτρους. Αν υπάρχουν N ορίσματα θέσης,
τοποθετούνται στις πρώτες N θέσεις. Στη συνέχεια, για κάθε όρισμα
λέξης-κλειδιού, το αναγνωριστικό χρησιμοποιείται για να καθοριστεί η
αντίστοιχη θέση (αν το αναγνωριστικό είναι το ίδιο με το όνομα της
πρώτης τυπικής παραμέτρου, χρησιμοποιείται η πρώτη θέση, και ούτω
καθεξής). Αν η θέση είναι ήδη συμπληρωμένη, γίνεται raise μια εξαίρεση
"TypeError". Διαφορετικά, το όρισμα τοποθετείται στη θέση,
συμπληρώνοντάς την (ακόμα και αν η έκφραση είναι "None", συμπληρώνει
τη θέση). Όταν έχουν υποστεί επεξεργασία όλα τα ορίσματα, οι θέσεις
που είναι ακόμα μη συμπληρωμένες συμπληρώνονται με την αντίστοιχη
προεπιλεγμένη τιμή από τον ορισμό της συνάρτησης. (Οι προεπιλεγμένες
τιμές υπολογίζονται, μία φορά, όταν ορίζεται η συνάρτηση· επομένως,
ένα μεταβλητό αντικείμενο όπως μια λίστα ή ένα λεξικό που
χρησιμοποιείται ως προεπιλεγμένη τιμή θα μοιράζεται από όλες τις
κλήσεις που δεν καθορίζουν μια τιμή ορίσματος για την αντίστοιχη θέση·
αυτό θα πρέπει συνήθως να αποφεύγεται.) Αν υπάρχουν τυχόν μη
συμπληρωμένες θέσεις για τις οποίες δεν καθορίζεται προεπιλεγμένη
τιμή, γίνεται raise μια εξαίρεση "TypeError". Διαφορετικά, η λίστα των
συμπληρωμένων θέσεων χρησιμοποιείται ως η λίστα ορισμάτων για την
κλήση.

Μια υλοποίηση μπορεί να παρέχει ενσωματωμένες συναρτήσεις των οποίων
οι παράμετροι θέσης δεν έχουν ονόματα, ακόμα και αν είναι 'επώνυμες'
για τους σκοπούς της τεκμηρίωσης, και οι οποίες επομένως δεν μπορούν
να παρασχεθούν μέσω λέξης-κλειδιού. Στην CPython, αυτό συμβαίνει για
συναρτήσεις υλοποιημένες σε C που χρησιμοποιούν την
"PyArg_ParseTuple()" για την ανάλυση των ορισμάτων τους.

Αν υπάρχουν περισσότερα ορίσματα θέσης από ό,τι θέσεις τυπικών
παραμέτρων, γίνεται raise μια εξαίρεση "TypeError", εκτός αν υπάρχει
μια τυπική παράμετρος που χρησιμοποιεί τη σύνταξη "*identifier"· σε
αυτή την περίπτωση, αυτή η τυπική παράμετρος λαμβάνει μια πλειάδα που
περιέχει τα πλεονάζοντα ορίσματα θέσης (ή μια άδεια πλειάδα αν δεν
υπάρχουν πλεονάζοντα ορίσματα θέσης).

Αν οποιοδήποτε όρισμα λέξης-κλειδιού δεν αντιστοιχεί σε όνομα τυπικής
παραμέτρου, γίνεται raise μια εξαίρεση "TypeError", εκτός αν υπάρχει
μια τυπική παράμετρος που χρησιμοποιεί τη σύνταξη "**identifier"· σε
αυτή την περίπτωση, αυτή η τυπική παράμετρος λαμβάνει ένα λεξικό που
περιέχει τα πλεονάζοντα ορίσματα λέξης-κλειδιού (χρησιμοποιώντας τις
λέξεις-κλειδιά ως κλειδιά και τις τιμές των ορισμάτων ως αντίστοιχες
τιμές), ή ένα (νέο) άδειο λεξικό αν δεν υπάρχουν πλεονάζοντα ορίσματα
λέξης-κλειδιού.

Αν η σύνταξη "*expression" εμφανίζεται στην κλήση της συνάρτησης, η
"expression" πρέπει να αποτιμάται σε ένα *iterable*. Τα στοιχεία των
iterables αντιμετωπίζονται σαν να είναι πρόσθετα ορίσματα θέσης. Για
την κλήση "f(x1, x2, *y, x3, x4)", αν το *y* αποτιμάται σε μια
ακολουθία *y1*, ..., *yM*, αυτό είναι ισοδύναμο με μια κλήση με M+4
ορίσματα θέσης *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" πρέπει να αποτιμάται σε ένα *mapping*, τα περιεχόμενα της
οποίας αντιμετωπίζονται ως πρόσθετα ορίσματα λέξης-κλειδιού. Αν σε μια
παράμετρο που ταιριάζει με ένα κλειδί έχει ήδη δοθεί μια τιμή (από ένα
ρητό όρισμα λέξης-κλειδιού, ή από άλλη αποσυσκευασία), γίνεται raise
μια εξαίρεση "TypeError".

Όταν χρησιμοποιείται η "**expression", κάθε κλειδί σε αυτή την
αντιστοίχιση πρέπει να είναι ένα αλφαριθμητικό. Κάθε τιμή από την
αντιστοίχιση ανατίθεται στην πρώτη τυπική παράμετρο που είναι
επιλέξιμη για ανάθεση μέσω λέξης-κλειδιού και της οποίας το όνομα
είναι ίσο με το κλειδί. Ένα κλειδί δεν χρειάζεται να είναι
αναγνωριστικό της Python (π.χ. το ""max-temp °F"" είναι αποδεκτό, αν
και δεν θα ταιριάξει με καμία τυπική παράμετρο που θα μπορούσε να
δηλωθεί). Αν δεν υπάρχει αντιστοιχία σε τυπική παράμετρο, το ζεύγος
κλειδιού-τιμής συλλέγεται από την παράμετρο "**", αν υπάρχει, ή αν δεν
υπάρχει, γίνεται raise μια εξαίρεση "TypeError".

Τυπικές παράμετροι που χρησιμοποιούν τη σύνταξη "*identifier" ή
"**identifier" δεν μπορούν να χρησιμοποιηθούν ως θέσεις ορισμάτων ή ως
ονόματα ορισμάτων λέξης-κλειδιού.

Άλλαξε στην έκδοση 3.5: Οι κλήσεις συναρτήσεων δέχονται οποιονδήποτε
αριθμό αποσυσκευασιών "*" και "**", τα ορίσματα θέσης μπορούν να
ακολουθούν αποσυσκευασίες iterable ("*"), και τα ορίσματα
λέξης-κλειδιού μπορούν να ακολουθούν αποσυσκευασίες λεξικού ("**").
Προτάθηκε αρχικά από το **PEP 448**.

Μια κλήση επιστρέφει πάντα κάποια τιμή, πιθανώς "None", εκτός αν κάνει
raise μια εξαίρεση. Το πώς υπολογίζεται αυτή η τιμή εξαρτάται από τον
τύπο του καλέσιμου αντικειμένου.

Αν είναι---

μια ορισμένη από τον χρήστη συνάρτηση:
   Το μπλοκ κώδικα της συνάρτησης εκτελείται, περνώντας του τη λίστα
   ορισμάτων. Το πρώτο πράγμα που θα κάνει το μπλοκ κώδικα είναι να
   συνδέσει τις τυπικές παραμέτρους με τα ορίσματα· αυτό περιγράφεται
   στην ενότητα Ορισμοί συναρτήσεων. Όταν το μπλοκ κώδικα εκτελεί μια
   πρόταση "return", αυτή καθορίζει την τιμή επιστροφής της κλήσης της
   συνάρτησης. Αν η εκτέλεση φτάσει στο τέλος του μπλοκ κώδικα χωρίς
   να εκτελέσει μια πρόταση "return", η τιμή επιστροφής είναι "None".

μια ενσωματωμένη συνάρτηση ή μέθοδος:
   Το αποτέλεσμα εξαρτάται από τον διερμηνέα· δείτε το Built-in
   functions για τις περιγραφές των ενσωματωμένων συναρτήσεων και
   μεθόδων.

ένα αντικείμενο κλάσης:
   Επιστρέφεται ένα νέο στιγμιότυπο αυτής της κλάσης.

μια μέθοδος στιγμιoτύπου κλάσης:
   Η αντίστοιχη ορισμένη από τον χρήστη συνάρτηση καλείται, με μια
   λίστα ορισμάτων που είναι κατά ένα μεγαλύτερη από τη λίστα
   ορισμάτων της κλήσης: το στιγμιότυπο γίνεται το πρώτο όρισμα.

ένα στιγμιότυπο κλάσης:
   Η κλάση πρέπει να ορίζει μια μέθοδο "__call__()"· το αποτέλεσμα
   είναι τότε το ίδιο σαν να είχε κληθεί αυτή η μέθοδος.


6.4. Έκφραση await
==================

Αναστέλλει την εκτέλεση της *coroutine* πάνω σε ένα αντικείμενο
*awaitable*. Μπορεί να χρησιμοποιηθεί μόνο μέσα σε μια *coroutine
function*.

   await_expr: "await" primary

Added in version 3.5.


6.5. Ο τελεστής δύναμης
=======================

Ο τελεστής δύναμης δεσμεύει πιο σφιχτά από τους μοναδιαίους τελεστές
στα αριστερά του· δεσμεύει λιγότερο σφιχτά από τους μοναδιαίους
τελεστές στα δεξιά του. Η σύνταξη είναι:

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

Έτσι, σε μια ακολουθία τελεστών δύναμης και μοναδιαίων τελεστών χωρίς
παρενθέσεις, οι τελεστές αποτιμώνται από τα δεξιά προς τα αριστερά
(αυτό δεν περιορίζει τη σειρά αποτίμησης για τους τελεστέους): το
"-1**2" έχει ως αποτέλεσμα "-1".

The power operator has the same semantics as the built-in "pow()"
function, when called with two arguments: it yields its left argument
raised to the power of its right argument. Numeric arguments are first
converted to a common type, and the result is of that type.

Για ακέραιους τελεστέους, το αποτέλεσμα έχει τον ίδιο τύπο με τους
τελεστέους, εκτός αν το δεύτερο όρισμα είναι αρνητικό· σε αυτή την
περίπτωση, όλα τα ορίσματα μετατρέπονται σε float και παραδίδεται ένα
αποτέλεσμα float. Για παράδειγμα, το "10**2" επιστρέφει "100", αλλά το
"10**-2" επιστρέφει "0.01".

Η ύψωση του "0.0" σε αρνητική δύναμη έχει ως αποτέλεσμα να γίνει raise
το "ZeroDivisionError". Η ύψωση ενός αρνητικού αριθμού σε κλασματική
δύναμη έχει ως αποτέλεσμα έναν "complex" αριθμό. (Σε παλαιότερες
εκδόσεις γινόταν raise το "ValueError".)

Αυτή η λειτουργία μπορεί να προσαρμοστεί χρησιμοποιώντας τις ειδικές
μεθόδους "__pow__()" και "__rpow__()".


6.6. Μοναδιαίες αριθμητικές και bitwise λειτουργίες
===================================================

Όλες οι μοναδιαίες αριθμητικές και bitwise λειτουργίες έχουν την ίδια
προτεραιότητα:

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

Ο μοναδιαίος τελεστής "-" (μείον) αποδίδει την αρνητικότητα του
αριθμητικού του ορίσματος· η λειτουργία μπορεί να υπερκαλυφθεί με την
ειδική μέθοδο "__neg__()".

Ο μοναδιαίος τελεστής "+" (συν) αποδίδει το αριθμητικό του όρισμα
αμετάβλητο· η λειτουργία μπορεί να υπερκαλυφθεί με την ειδική μέθοδο
"__pos__()".

Ο μοναδιαίος τελεστής "~" (αντιστροφή) αποδίδει την bitwise αντιστροφή
του ακέραιου ορίσματός του. Η bitwise αντιστροφή του "x" ορίζεται ως
"-(x+1)". Εφαρμόζεται μόνο σε ακέραιους αριθμούς ή σε προσαρμοσμένα
αντικείμενα που υπερκαλύπτουν την ειδική μέθοδο "__invert__()".

Και στις τρεις περιπτώσεις, αν το όρισμα δεν έχει τον σωστό τύπο,
γίνεται raise μια εξαίρεση "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

The "*" (multiplication) operator yields the product of its arguments.
The arguments must either both be numbers, or one argument must be an
integer and the other must be a sequence. In the former case, the
numbers are converted to a common real type and then multiplied
together.  In the latter case, sequence repetition is performed; a
negative repetition factor yields an empty sequence.

Αυτή η λειτουργία μπορεί να προσαρμοστεί χρησιμοποιώντας τις ειδικές
μεθόδους "__mul__()" και "__rmul__()".

Άλλαξε στην έκδοση 3.14: Αν μόνο ένας τελεστέος είναι μιγαδικός
αριθμός, ο άλλος τελεστέος μετατρέπεται σε αριθμό κινητής
υποδιαστολής.

Ο τελεστής "@" (at) προορίζεται να χρησιμοποιηθεί για πολλαπλασιασμό
πινάκων. Κανένας ενσωματωμένος τύπος της Python δεν υλοποιεί αυτόν τον
τελεστή.

Αυτή η λειτουργία μπορεί να προσαρμοστεί χρησιμοποιώντας τις ειδικές
μεθόδους "__matmul__()" και "__rmatmul__()".

Added in version 3.5.

The "/" (division) and "//" (floor division) operators yield the
quotient of their arguments.  The numeric arguments are first
converted to a common type. Division of integers yields a float, while
floor division of integers results in an integer; the result is that
of mathematical division with the 'floor' function applied to the
result.  Division by zero raises the "ZeroDivisionError" exception.

Η λειτουργία της διαίρεσης μπορεί να προσαρμοστεί χρησιμοποιώντας τις
ειδικές μεθόδους "__truediv__()" και "__rtruediv__()". Η λειτουργία
της διαίρεσης με στρογγυλοποίηση προς τα κάτω μπορεί να προσαρμοστεί
χρησιμοποιώντας τις ειδικές μεθόδους "__floordiv__()" και
"__rfloordiv__()".

The "%" (modulo) operator yields the remainder from the division of
the first argument by the second.  The numeric arguments are first
converted to a common type. A zero right argument raises the
"ZeroDivisionError" exception.  The arguments may be floating-point
numbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals "4*0.7 +
0.34".)  The modulo operator always yields a result with the same sign
as its second operand (or zero); the absolute value of the result is
strictly smaller than the absolute value of the second operand [1].

Οι τελεστές διαίρεσης με στρογγυλοποίηση προς τα κάτω και modulo
συνδέονται με την ακόλουθη ταυτότητα: "x == (x//y)*y + (x%y)". Η
διαίρεση με στρογγυλοποίηση προς τα κάτω και το modulo συνδέονται
επίσης με την ενσωματωμένη συνάρτηση "divmod()": "divmod(x, y) ==
(x//y, x%y)". [2].

Εκτός από την εκτέλεση της λειτουργίας modulo σε αριθμούς, ο τελεστής
"%" υπερφορτώνεται επίσης από τα αντικείμενα αλφαριθμητικών για να
εκτελεί μορφοποίηση αλφαριθμητικών παλαιού τύπου (γνωστή και ως
παρεμβολή). Η σύνταξη για τη μορφοποίηση αλφαριθμητικών περιγράφεται
στην Αναφορά Βιβλιοθήκης της Python, στην ενότητα printf-style String
Formatting.

Η λειτουργία *modulo* μπορεί να προσαρμοστεί χρησιμοποιώντας τις
ειδικές μεθόδους "__mod__()" και "__rmod__()".

Ο τελεστής διαίρεσης με στρογγυλοποίηση προς τα κάτω, ο τελεστής
modulo και η συνάρτηση "divmod()" δεν ορίζονται για μιγαδικούς
αριθμούς. Αντίθετα, μετατρέψτε σε αριθμό κινητής υποδιαστολής
χρησιμοποιώντας τη συνάρτηση "abs()" αν χρειάζεται.

The "+" (addition) operator yields the sum of its arguments.  The
arguments must either both be numbers or both be sequences of the same
type.  In the former case, the numbers are converted to a common real
type and then added together. In the latter case, the sequences are
concatenated.

Αυτή η λειτουργία μπορεί να προσαρμοστεί χρησιμοποιώντας τις ειδικές
μεθόδους "__add__()" και "__radd__()".

Άλλαξε στην έκδοση 3.14: Αν μόνο ένας τελεστέος είναι μιγαδικός
αριθμός, ο άλλος τελεστέος μετατρέπεται σε αριθμό κινητής
υποδιαστολής.

The "-" (subtraction) operator yields the difference of its arguments.
The numeric arguments are first converted to a common real type.

Αυτή η λειτουργία μπορεί να προσαρμοστεί χρησιμοποιώντας τις ειδικές
μεθόδους "__sub__()" και "__rsub__()".

Άλλαξε στην έκδοση 3.14: Αν μόνο ένας τελεστέος είναι μιγαδικός
αριθμός, ο άλλος τελεστέος μετατρέπεται σε αριθμό κινητής
υποδιαστολής.


6.8. Λειτουργίες μετατόπισης
============================

Οι λειτουργίες μετατόπισης έχουν χαμηλότερη προτεραιότητα από τις
αριθμητικές λειτουργίες:

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

Αυτοί οι τελεστές δέχονται ακέραιους ως ορίσματα. Μετατοπίζουν το
πρώτο όρισμα προς τα αριστερά ή προς τα δεξιά κατά τον αριθμό των bits
που δίνεται από το δεύτερο όρισμα.

Η λειτουργία αριστερής μετατόπισης μπορεί να προσαρμοστεί
χρησιμοποιώντας τις ειδικές μεθόδους "__lshift__()" και
"__rlshift__()". Η λειτουργία δεξιάς μετατόπισης μπορεί να
προσαρμοστεί χρησιμοποιώντας τις ειδικές μεθόδους "__rshift__()" και
"__rrshift__()".

Μια δεξιά μετατόπιση κατά *n* bits ορίζεται ως διαίρεση με
στρογγυλοποίηση προς τα κάτω με το "pow(2,n)". Μια αριστερή μετατόπιση
κατά *n* bits ορίζεται ως πολλαπλασιασμός με το "pow(2,n)".


6.9. Δυαδικές λειτουργίες bitwise
=================================

Κάθε μία από τις τρεις λειτουργίες bitwise έχει διαφορετικό επίπεδο
προτεραιότητας:

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

Ο τελεστής "&" αποδίδει το bitwise AND των ορισμάτων του, τα οποία
πρέπει να είναι ακέραιοι ή ένα από αυτά πρέπει να είναι ένα
προσαρμοσμένο αντικείμενο που παρακάμπτει τις ειδικές μεθόδους
"__and__()" ή "__rand__()".

Ο τελεστής "^" αποδίδει το bitwise XOR (αποκλειστικό OR) των ορισμάτων
του, τα οποία πρέπει να είναι ακέραιοι ή ένα από αυτά πρέπει να είναι
ένα προσαρμοσμένο αντικείμενο που παρακάμπτει τις ειδικές μεθόδους
"__xor__()" ή "__rxor__()".

Ο τελεστής "|" αποδίδει το bitwise (συμπεριληπτικό) OR των ορισμάτων
του, τα οποία πρέπει να είναι ακέραιοι ή ένα από αυτά πρέπει να είναι
ένα προσαρμοσμένο αντικείμενο που παρακάμπτει τις ειδικές μεθόδους
"__or__()" ή "__ror__()".


6.10. Συγκρίσεις
================

Σε αντίθεση με τη C, όλες οι λειτουργίες σύγκρισης στην Python έχουν
την ίδια προτεραιότητα, η οποία είναι χαμηλότερη από οποιασδήποτε
αριθμητικής, μετατόπισης ή bitwise λειτουργίας. Επίσης σε αντίθεση με
τη C, εκφράσεις όπως το "a < b < c" έχουν την ερμηνεία που είναι
συμβατική στα μαθηματικά:

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

Οι συγκρίσεις αποδίδουν λογικές τιμές: "True" ή "False". Οι
προσαρμοσμένες *rich comparison methods* μπορεί να επιστρέψουν μη
λογικές τιμές. Σε αυτή την περίπτωση, η Python θα καλέσει την "bool()"
σε μια τέτοια τιμή σε λογικά πλαίσια.

Οι συγκρίσεις μπορούν να είναι αυθαίρετα αλυσιδωτές, π.χ., το "x < y
<= z" είναι ισοδύναμο με το "x < y and y <= z", με τη διαφορά ότι το
"y" αποτιμάται μόνο μία φορά (αλλά και στις δύο περιπτώσεις το "z" δεν
αποτιμάται καθόλου όταν το "x < y" βρεθεί να είναι ψευδές).

Τυπικά, αν *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. Συγκρίσεις τιμών
------------------------

Οι τελεστές "<", ">", "==", ">=", "<=", και "!=" συγκρίνουν τις τιμές
δύο αντικειμένων. Τα αντικείμενα δεν χρειάζεται να έχουν τον ίδιο
τύπο.

Το κεφάλαιο Αντικείμενα, τιμές και τύποι αναφέρει ότι τα αντικείμενα
έχουν μια τιμή (εκτός από τύπο και ταυτότητα). Η τιμή ενός
αντικειμένου είναι μια μάλλον αφηρημένη έννοια στην Python: Για
παράδειγμα, δεν υπάρχει κανονική μέθοδος πρόσβασης για την τιμή ενός
αντικειμένου. Επίσης, δεν υπάρχει απαίτηση η τιμή ενός αντικειμένου να
κατασκευάζεται με συγκεκριμένο τρόπο, π.χ. να αποτελείται από όλες τις
ιδιότητες δεδομένων του. Οι τελεστές σύγκρισης υλοποιούν μια
συγκεκριμένη έννοια του τι είναι η τιμή ενός αντικειμένου. Μπορεί
κανείς να σκεφτεί ότι ορίζουν την τιμή ενός αντικειμένου έμμεσα, μέσω
της υλοποίησης της σύγκρισής τους.

Επειδή όλοι οι τύποι είναι (άμεσοι ή έμμεσοι) υποτύποι του "object",
κληρονομούν την προεπιλεγμένη συμπεριφορά σύγκρισης από το "object".
Οι τύποι μπορούν να προσαρμόσουν τη συμπεριφορά σύγκρισής τους
υλοποιώντας *rich comparison methods* όπως η "__lt__()", που
περιγράφονται στο Βασική προσαρμογή.

Η προεπιλεγμένη συμπεριφορά για τη σύγκριση ισότητας ("==" και "!=")
βασίζεται στην ταυτότητα των αντικειμένων. Συνεπώς, η σύγκριση
ισότητας στιγμιότυπων με την ίδια ταυτότητα καταλήγει σε ισότητα, και
η σύγκριση ισότητας στιγμιότυπων με διαφορετικές ταυτότητες καταλήγει
σε ανισότητα. Ένα κίνητρο για αυτή την προεπιλεγμένη συμπεριφορά είναι
η επιθυμία όλα τα αντικείμενα να είναι ανακλαστικά (δηλαδή το "x is y"
να συνεπάγεται το "x == y").

Δεν παρέχεται προεπιλεγμένη σύγκριση διάταξης ("<", ">", "<=", και
">=")· μια προσπάθεια κάνει raise το "TypeError". Ένα κίνητρο για αυτή
την προεπιλεγμένη συμπεριφορά είναι η έλλειψη ενός παρόμοιου
αμετάβλητου όπως για την ισότητα.

Η συμπεριφορά της προεπιλεγμένης σύγκρισης ισότητας, ότι στιγμιότυπα
με διαφορετικές ταυτότητες είναι πάντα άνισα, μπορεί να έρχεται σε
αντίθεση με αυτό που θα χρειαστούν τύποι που έχουν έναν λογικό ορισμό
τιμής αντικειμένου και ισότητας βασισμένης στην τιμή. Τέτοιοι τύποι θα
χρειαστεί να προσαρμόσουν τη συμπεριφορά σύγκρισής τους, και πράγματι,
διάφοροι ενσωματωμένοι τύποι το έχουν κάνει.

Η ακόλουθη λίστα περιγράφει τη συμπεριφορά σύγκρισης των πιο
σημαντικών ενσωματωμένων τύπων.

* Οι αριθμοί των ενσωματωμένων αριθμητικών τύπων (Numeric Types ---
  int, float, complex) και των τύπων της τυπικής βιβλιοθήκης
  "fractions.Fraction" και "decimal.Decimal" μπορούν να συγκριθούν
  μεταξύ τους και με άλλους τύπους, με τον περιορισμό ότι οι μιγαδικοί
  αριθμοί δεν υποστηρίζουν σύγκριση διάταξης. Μέσα στα όρια των
  εμπλεκόμενων τύπων, συγκρίνονται μαθηματικά (αλγοριθμικά) σωστά
  χωρίς απώλεια ακρίβειας.

  Οι μη αριθμητικές τιμές "float('NaN')" και "decimal.Decimal('NaN')"
  είναι ειδικές. Οποιαδήποτε διατεταγμένη σύγκριση ενός αριθμού με μια
  μη αριθμητική τιμή είναι ψευδής. Μια αντισυμβατική συνέπεια είναι
  ότι οι μη αριθμητικές τιμές δεν είναι ίσες με τον εαυτό τους. Για
  παράδειγμα, αν "x = float('NaN')", τα "3 < x", "x < 3" και "x == x"
  είναι όλα ψευδή, ενώ το "x != x" είναι αληθές. Αυτή η συμπεριφορά
  συμμορφώνεται με το πρότυπο IEEE 754.

* Το "None" και το "NotImplemented" είναι singletons. Το **PEP 8**
  συμβουλεύει ότι οι συγκρίσεις για τα singletons θα πρέπει πάντα να
  γίνονται με το "is" ή το "is not", ποτέ με τους τελεστές ισότητας.

* Οι δυαδικές ακολουθίες (στιγμιότυπα της "bytes" ή της "bytearray")
  μπορούν να συγκριθούν μεταξύ τους και με άλλους τύπους. Συγκρίνονται
  λεξικογραφικά χρησιμοποιώντας τις αριθμητικές τιμές των στοιχείων
  τους.

* Τα αλφαριθμητικά (στιγμιότυπα της "str") συγκρίνονται λεξικογραφικά
  χρησιμοποιώντας τα αριθμητικά σημεία κώδικα Unicode (το αποτέλεσμα
  της ενσωματωμένης συνάρτησης "ord()") των χαρακτήρων τους. [3]

  Αλφαριθμητικά και δυαδικές ακολουθίες δεν μπορούν να συγκριθούν
  άμεσα.

* Οι ακολουθίες (στιγμιότυπα της "tuple", "list", ή "range") μπορούν
  να συγκριθούν μόνο εντός του τύπου τους, με τον περιορισμό ότι τα
  εύρη δεν υποστηρίζουν σύγκριση διάταξης. Η σύγκριση ισότητας μεταξύ
  αυτών των τύπων καταλήγει σε ανισότητα, και η σύγκριση διάταξης
  μεταξύ αυτών των τύπων κάνει raise το "TypeError".

  Οι ακολουθίες συγκρίνονται λεξικογραφικά χρησιμοποιώντας σύγκριση
  των αντίστοιχων στοιχείων. Οι ενσωματωμένοι υποδοχείς υποθέτουν
  τυπικά ότι τα πανομοιότυπα αντικείμενα είναι ίσα με τον εαυτό τους.
  Αυτό τους επιτρέπει να παρακάμπτουν τους ελέγχους ισότητας για
  πανομοιότυπα αντικείμενα ώστε να βελτιώσουν την απόδοση και να
  διατηρήσουν τα εσωτερικά τους αμετάβλητα.

  Η λεξικογραφική σύγκριση μεταξύ ενσωματωμένων συλλογών λειτουργεί ως
  εξής:

  * Για να είναι δύο συλλογές ίσες, πρέπει να είναι του ίδιου τύπου,
    να έχουν το ίδιο μήκος, και κάθε ζεύγος αντίστοιχων στοιχείων
    πρέπει να είναι ίσο (για παράδειγμα, το "[1,2] == (1,2)" είναι
    ψευδές επειδή ο τύπος δεν είναι ο ίδιος).

  * Οι συλλογές που υποστηρίζουν σύγκριση διάταξης στοιχίζονται με τον
    ίδιο τρόπο όπως γίνεται με τα πρώτα άνισα στοιχεία τους (για
    παράδειγμα, το "[1,2,x] <= [1,2,y]" έχει την ίδια τιμή με το "x <=
    y"). Αν δεν υπάρχει αντίστοιχο στοιχείο, η συντομότερη συλλογή
    προηγείται (για παράδειγμα, το "[1,2] < [1,2,3]" είναι αληθές).

* Οι αντιστοιχίσεις (στιγμιότυπα της "dict") είναι ίσες αν και μόνο αν
  έχουν ίσα ζεύγη "(κλειδί, τιμή)". Η σύγκριση ισότητας των κλειδιών
  και των τιμών επιβάλλει την ανακλαστικότητα.

  Οι συγκρίσεις διάταξης ("<", ">", "<=", και ">=") κάνουν raise το
  "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" (για ολική διάταξη)

  The last two expressions apply to totally ordered collections (e.g.
  to sequences, but not to sets or mappings). See also the
  "@~functools.total_ordering" decorator.

* Το αποτέλεσμα της "hash()" θα πρέπει να είναι συνεπές με την
  ισότητα. Αντικείμενα που είναι ίσα θα πρέπει είτε να έχουν την ίδια
  τιμή κατακερματισμού, είτε να επισημαίνονται ως μη κατακερματιστέα.

Η Python δεν επιβάλλει αυτούς τους κανόνες συνέπειας. Στην
πραγματικότητα, οι μη αριθμητικές τιμές αποτελούν παράδειγμα μη
τήρησης αυτών των κανόνων.


6.10.2. Λειτουργίες ελέγχου συμμετοχής
--------------------------------------

Οι τελεστές "in" και "not in" ελέγχουν για τη συμμετοχή. Το "x in s"
αποτιμάται σε "True" αν το *x* είναι μέλος του *s*, και "False"
διαφορετικά. Το "x not in s" επιστρέφει την άρνηση του "x in s". Όλες
οι ενσωματωμένες ακολουθίες και οι τύποι συνόλων το υποστηρίζουν αυτό,
καθώς και τα λεξικά, για τα οποία το "in" ελέγχει αν το λεξικό έχει
ένα δεδομένο κλειδί. Για τύπους υποδοχέων όπως list, tuple, set,
frozenset, dict, ή collections.deque, η έκφραση "x in y" είναι
ισοδύναμη με "any(x is e or x == e for e in y)".

Για τους τύπους string και bytes, το "x in y" είναι "True" αν και μόνο
αν το *x* είναι υπο-αλφαριθμητικό του *y*. Ένας ισοδύναμος έλεγχος
είναι το "y.find(x) != -1". Τα κενά αλφαριθμητικά θεωρούνται πάντα
υπο-αλφαριθμητικά οποιουδήποτε άλλου αλφαριθμητικού, οπότε το """ in
"abc"" θα επιστρέψει "True".

Για ορισμένες από τον χρήστη κλάσεις που ορίζουν τη μέθοδο
"__contains__()", το "x in y" επιστρέφει "True" αν το
"y.__contains__(x)" επιστρέψει μια αληθή τιμή, και "False"
διαφορετικά.

Για ορισμένες από τον χρήστη κλάσεις που δεν ορίζουν τη
"__contains__()" αλλά ορίζουν τη "__iter__()", το "x in y" είναι
"True" αν κάποια τιμή "z", για την οποία η έκφραση "x is z or x == z"
είναι αληθής, παραχθεί κατά την επανάληψη πάνω στο "y". Αν γίνει raise
εξαίρεση κατά τη διάρκεια της επανάληψης, είναι σαν το "in" να έκανε
raise αυτήν την εξαίρεση.

Τέλος, δοκιμάζεται το παλαιού τύπου πρωτόκολλο επανάληψης: αν μια
κλάση ορίζει τη "__getitem__()", το "x in y" είναι "True" αν και μόνο
αν υπάρχει ένας μη αρνητικός ακέραιος δείκτης *i* τέτοιος ώστε "x is
y[i] or x == y[i]", και κανένας μικρότερος ακέραιος δείκτης δεν κάνει
raise την εξαίρεση "IndexError". (Αν γίνει raise οποιαδήποτε άλλη
εξαίρεση, είναι σαν το "in" να έκανε raise αυτήν την εξαίρεση).

Ο τελεστής "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", το αριθμητικό μηδέν όλων των
τύπων, και τα κενά αλφαριθμητικά και υποδοχείς (συμπεριλαμβανομένων
των strings, tuples, lists, dictionaries, sets και frozensets). Όλες
οι άλλες τιμές ερμηνεύονται ως αληθείς. Τα ορισμένα από τον χρήστη
αντικείμενα μπορούν να προσαρμόσουν την αληθή τιμή τους παρέχοντας μια
μέθοδο "__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

Μια έκφραση ανάθεσης (μερικές φορές ονομάζεται επίσης "επώνυμη
έκφραση" ή "walrus") αναθέτει μια "expression" σε ένα "identifier",
ενώ ταυτόχρονα επιστρέφει την τιμή της "expression".

Μια κοινή περίπτωση χρήσης είναι κατά τον χειρισμό ταιριασμένων
regular expressions:

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

Ή, κατά την επεξεργασία μιας ροής αρχείου σε κομμάτια:

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

Οι εκφράσεις ανάθεσης πρέπει να περιβάλλονται από παρενθέσεις όταν
χρησιμοποιούνται ως προτάσεις εκφράσεων και όταν χρησιμοποιούνται ως
υπο-εκφράσεις σε τεμαχισμό, εκφράσεις υπό συνθήκη, lambda, ορίσματα
λέξης-κλειδιού , και εκφράσεις comprehension-if, καθώς και σε
προτάσεις "assert", "with", και "assignment". Σε όλα τα άλλα σημεία
όπου μπορούν να χρησιμοποιηθούν, οι παρενθέσεις δεν είναι απαραίτητες,
συμπεριλαμβανομένων των προτάσεων "if" και "while".

Added in version 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
======================

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

Οι εκφράσεις lambda (μερικές φορές ονομάζονται μορφές lambda)
χρησιμοποιούνται για τη δημιουργία ανώνυμων συναρτήσεων. Η έκφραση
"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.

Added in version 3.5: Η αποσυσκευασία του iterable σε λίστες εκφράσεων
προτάθηκε αρχικά από το **PEP 448**.

Added in version 3.11: Οποιοδήποτε στοιχείο σε μια λίστα εκφράσεων
μπορεί να φέρει αστερίσκο. Δείτε το **PEP 646**.


6.16. Αποτίμηση διάταξης
========================

Η Python αποτιμά τις εκφράσεις από αριστερά προς τα δεξιά. Παρατηρήστε
ότι κατά την αποτίμηση μιας ανάθεσης, η δεξιά πλευρά αποτιμάται πριν
από την αριστερή πλευρά.

Στις ακόλουθες γραμμές, οι εκφράσεις θα αποτιμηθούν με την αριθμητική
σειρά των καταλήξεών τους:

   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. Προτεραιότητα τελεστών
============================

Ο ακόλουθος πίνακας συνοψίζει την προτεραιότητα των τελεστών στην
Python, από την υψηλότερη προτεραιότητα (πιο ισχυρή δέσμευση) στη
χαμηλότερη προτεραιότητα (λιγότερο ισχυρή δέσμευση). Οι τελεστές στο
ίδιο πλαίσιο έχουν την ίδια προτεραιότητα. Εκτός αν δίνεται ρητά η
σύνταξη, οι τελεστές είναι δυαδικοί. Οι τελεστές στο ίδιο πλαίσιο
ομαδοποιούνται από αριστερά προς τα δεξιά (εκτός από την ύψωση σε
δύναμη και τις εκφράσεις υπό συνθήκη, που ομαδοποιούνται από δεξιά
προς τα αριστερά).

Σημειώστε ότι οι συγκρίσεις, οι έλεγχοι συμμετοχής, και οι έλεγχοι
ταυτότητας, έχουν όλοι την ίδια προτεραιότητα και διαθέτουν το
χαρακτηριστικό της αλυσίδας από αριστερά προς τα δεξιά όπως
περιγράφεται στην ενότητα Συγκρίσεις.

+-------------------------------------------------+---------------------------------------+
| Τελεστής                                        | Περιγραφή                             |
|=================================================|=======================================|
| "(expressions...)",  "[expressions...]", "{key: | Δεσμευτική ή σε παρένθεση έκφραση,    |
| value...}", "{expressions...}"                  | απεικόνιση λίστας, απεικόνιση         |
|                                                 | λεξικού, απεικόνιση συνόλου           |
+-------------------------------------------------+---------------------------------------+
| "x[index]", "x[index:index]" "x(arguments...)", | Subscription (including slicing),     |
| "x.attribute"                                   | call, attribute reference             |
+-------------------------------------------------+---------------------------------------+
| "await x"                                       | Έκφραση await                         |
+-------------------------------------------------+---------------------------------------+
| "**"                                            | Ύψωση σε δύναμη [5]                   |
+-------------------------------------------------+---------------------------------------+
| "+x", "-x", "~x"                                | Θετικό, αρνητικό, bitwise NOT         |
+-------------------------------------------------+---------------------------------------+
| "*", "@", "/", "//", "%"                        | Πολλαπλασιασμός, πολλαπλασιασμός      |
|                                                 | πινάκων, διαίρεση, διαίρεση με        |
|                                                 | στρογγυλοποίηση προς τα κάτω,         |
|                                                 | υπόλοιπο [6]                          |
+-------------------------------------------------+---------------------------------------+
| "+", "-"                                        | Πρόσθεση και αφαίρεση                 |
+-------------------------------------------------+---------------------------------------+
| "<<", ">>"                                      | Μετατοπίσεις                          |
+-------------------------------------------------+---------------------------------------+
| "&"                                             | Bitwise AND                           |
+-------------------------------------------------+---------------------------------------+
| "^"                                             | Bitwise XOR                           |
+-------------------------------------------------+---------------------------------------+
| "|"                                             | Bitwise OR                            |
+-------------------------------------------------+---------------------------------------+
| "in", "not in", "is", "is not", "<", "<=", ">", | Συγκρίσεις, συμπεριλαμβανομένων       |
| ">=", "!=", "=="                                | ελέγχων συμμετοχής και ελέγχων        |
|                                                 | ταυτότητας                            |
+-------------------------------------------------+---------------------------------------+
| "not x"                                         | Λογικό NOT                            |
+-------------------------------------------------+---------------------------------------+
| "and"                                           | Λογικό AND                            |
+-------------------------------------------------+---------------------------------------+
| "or"                                            | Λογικό OR                             |
+-------------------------------------------------+---------------------------------------+
| "if" -- "else"                                  | Έκφραση υπό συνθήκη                   |
+-------------------------------------------------+---------------------------------------+
| "lambda"                                        | Έκφραση lambda                        |
+-------------------------------------------------+---------------------------------------+
| ":="                                            | Έκφραση ανάθεσης                      |
+-------------------------------------------------+---------------------------------------+

-[ Υποσημειώσεις ]-

[1] Αν και το "abs(x%y) < abs(y)" είναι μαθηματικά αληθές, για τα
    floats μπορεί να μην είναι αριθμητικά αληθές λόγω σφαλμάτων
    στρογγυλοποίησης. Για παράδειγμα, και υποθέτοντας μια πλατφόρμα
    στην οποία το float της Python είναι αριθμός διπλής ακρίβειας κατά
    το IEEE 754, προκειμένου το "-1e-100 % 1e100" να έχει το ίδιο
    πρόσημο με το "1e100", το υπολογισμένο αποτέλεσμα είναι "-1e-100 +
    1e100", το οποίο είναι αριθμητικά ακριβώς ίσο με "1e100". Η
    συνάρτηση "math.fmod()" επιστρέφει ένα αποτέλεσμα του οποίου το
    πρόσημο ταιριάζει με το πρόσημο του πρώτου ορίσματος, και έτσι
    επιστρέφει "-1e-100" σε αυτήν την περίπτωση. Το ποια προσέγγιση
    είναι πιο κατάλληλη εξαρτάται από την εφαρμογή.

[2] Αν το x είναι πολύ κοντά σε ένα ακριβές ακέραιο πολλαπλάσιο του y,
    είναι πιθανό το "x//y" να είναι κατά ένα μεγαλύτερο από το
    "(x-x%y)//y" λόγω στρογγυλοποίησης. Σε τέτοιες περιπτώσεις, η
    Python επιστρέφει το δεύτερο αποτέλεσμα, προκειμένου να διατηρηθεί
    ότι το "divmod(x,y)[0] * y + x % y" είναι πολύ κοντά στο "x".

[3] Το πρότυπο Unicode διακρίνει μεταξύ των *code points* (π.χ.
    U+0041) και των *abstract characters* (π.χ. "ΛΑΤΙΝΙΚΟ ΚΕΦΑΛΑΙΟ
    ΓΡΑΜΜΑ A"). Παρόλο που οι περισσότεροι αφηρημένοι χαρακτήρες στο
    Unicode αναπαρίστανται χρησιμοποιώντας μόνο ένα σημείο κώδικα,
    υπάρχει ένας αριθμός αφηρημένων χαρακτήρων που μπορούν επιπλέον να
    αναπαρασταθούν χρησιμοποιώντας μια ακολουθία περισσότερων από ένα
    σημείων κώδικα. Για παράδειγμα, ο αφηρημένος χαρακτήρας "ΛΑΤΙΝΙΚΟ
    ΚΕΦΑΛΑΙΟ ΓΡΑΜΜΑ C ME CEDILLA" μπορεί να αναπαρασταθεί ως ένας
    ενιαίος *precomposed character* στη θέση toy κώδικα U+00C7, ή ως
    μια ακολουθία ενός *base character* στη θέση του κώδικα U+0043
    (ΛΑΤΙΝΙΚΟ ΚΕΦΑΛΑΙΟ ΓΡΑΜΜΑ C), ακολουθούμενου από έναν *combining
    character* στη θέση του κώδικα U+0327 (COMBINING CEDILLA).

    Οι τελεστές σύγκρισης στα αλφαριθμητικά συγκρίνουν στο επίπεδο των
    σημείων του κώδικα Unicode. Αυτό μπορεί να είναι αντισυμβατικό για
    τους ανθρώπους. Για παράδειγμα, το ""\u00C7" == "\u0043\u0327""
    είναι "False", παρόλο που και τα δύο αλφαριθμητικά αναπαριστούν
    τον ίδιο αφηρημένο χαρακτήρα "ΛΑΤΙΝΙΚΟ ΚΕΦΑΛΑΙΟ ΓΡΑΜΜΑ C ME
    CEDILLA".

    Για να συγκρίνετε αλφαριθμητικά στο επίπεδο των αφηρημένων
    χαρακτήρων (δηλαδή, με τρόπο διαισθητικό για τους ανθρώπους),
    χρησιμοποιήστε την "unicodedata.normalize()".

[4] Λόγω της αυτόματης συλλογής απορριμμάτων, των ελεύθερων λιστών,
    και της δυναμικής φύσης των περιγραφέων, μπορεί να παρατηρήσετε
    φαινομενικά ασυνήθιστη συμπεριφορά σε ορισμένες χρήσεις του
    τελεστή "is", όπως αυτές που περιλαμβάνουν συγκρίσεις μεταξύ
    μεθόδων στιγμιοτύπου ή σταθερών. Ελέγξτε την τεκμηρίωσή τους για
    περισσότερες πληροφορίες.

[5] Ο τελεστής δύναμης "**" δεσμεύει λιγότερο σφιχτά από έναν
    αριθμητικό ή bitwise μοναδιαίο τελεστή στα δεξιά του, δηλαδή, το
    "2**-1" είναι "0.5".

[6] Ο τελεστής "%" χρησιμοποιείται επίσης για μορφοποίηση
    αλφαριθμητικών· ισχύει η ίδια προτεραιότητα.
