1. Εισαγωγή

Αυτό το εγχειρίδιο αναφοράς περιγράφει την γλώσσα προγραμματισμού Python. Δεν προορίζεται ως εγχειρίδιο εκμάθησης.

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

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

Κάθε υλοποίηση της Python συνοδεύεται από έναν αριθμό ενσωματωμένων και πρότυπων module. Αυτές είναι καταγεγραμμένες στο The Python Standard Library. Κάποια ενσωματωμένα module αναφέρονται όταν αλληλεπιδρούν με έναν σημαντικό τρόπο με τον ορισμό της γλώσσας.

1.1. Εναλλακτικές Υλοποιήσεις

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

Γνωστές υλοποιήσεις περιλαμβάνουν:

CPython

Αυτή είναι η πρωτότυπη και η πιο καλοδιατηρημένη υλοποίηση της Python, γραμμένη στην C. Νέες λειτουργίες της γλώσσας συνήθως εμφανίζονται πρώτα εδώ.

Jython

Η υλοποίηση της Python στην Java. Αυτή η υλοποίηση μπορεί να χρησιμοποιηθεί ως γλώσσα δέσμης ενεργειών για εφαρμογές στην Java, ή μπορεί να χρησιμοποιηθεί για να δημιουργήσει εφαρμογές με τη χρήση των βιβλιοθηκών των κλάσεων της Java. Συχνά επίσης χρησιμοποιείται για να δημιουργήσει τεστ για τις βιβλιοθήκες της Java. Περισσότερες πληροφορίες μπορείτε να βρείτε στην ιστοσελίδα της Jython.

Python για το .NET

Αυτή η υλοποίηση στην πραγματικότητα χρησιμοποιεί την υλοποίηση CPython, αλλά είναι μία διαχειριζόμενη εφαρμογή του .NET και κάνει διαθέσιμες τις .NET βιβλιοθήκες. Δημιουργήθηκε από τον Brian Lloyd. Για περισσότερες πληροφορίες, δείτε την αρχική σελίδα της Python για το .NET.

IronPython

Μια εναλλακτική Python για το .NET. Σε αντίθεση με το Python.NET, αυτή είναι μία ολοκληρωμένη υλοποίηση της Python που παράγει IL, και κάνει μεταγλώττιση του κώδικα της Python απευθείας στη γλώσσα assembly του .NET. Δημιουργήθηκε από τον Jim Hugunin, τον πρωτότυπο δημιουργό της Jython. Για περισσότερες πληροφορίες δείτε την ιστοσελίδα της IronPython.

PyPy

Μια υλοποίηση της Python γραμμένη εξ ολοκλήρου σε Python. Υποστηρίζει αρκετές προηγμένες λειτουργίες που δεν υπάρχουν σε άλλες υλοποιήσεις όπως υποστήριξη για stackless και τον μεταγλωττιστή Just in Time. Ένας από τους στόχους του πρότζεκτ είναι να ενθαρρύνει τον πειραματισμό με την ίδια την γλώσσα κάνοντας πιο εύκολη την τροποποίηση του διερμηνέα (αφού είναι γραμμένος στην Python). Περισσότερες πληροφορίες είναι διαθέσιμες στην αρχική σελίδα του PyPy πρότζεκτ.

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

1.2. Σημειογραφία

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

name:   letter (letter | digit | "_")*
letter: "a"..."z" | "A"..."Z"
digit:  "0"..."9"

Σε αυτό το παράδειγμα, η πρώτη γραμμή αναφέρει ότι ένα name είναι ένα letter ακολουθούμενο από μια ακολουθία μηδενός ή περισσότερων γραμμάτοςων, ψηφίοα, και κάτω παύλων. Ένα letter με τη σειρά του είναι οποιοσδήποτε από τους μεμονωμένους χαρακτήρες 'a' έως 'z' και A έως Z``∙ ένα ``digit είναι ένας μεμονωμένος χαρακτήρας από 0 έως 9.

Κάθε κανόνας ξεκινά με ένα όνομα (το οποίο προσδιορίζει τον κανόνα που ορίζεται) ακολουθούμενο από άνω κάτω τελεία, :. Ο ορισμός στα δεξιά της άνω και κάτω τελείας χρησιμοποιεί τα ακόλουθα στοιχεία σύνταξης:

  • name: Ένα όνομα αναφέρεται σε έναν άλλο κανόνα, Όπου είναι δυνατόν, είναι ένας σύνδεσμος προς τον ορισμό του κανόνα.

    • TOKEN: Ένα κεφαλαίο όνομα αναφέρεται σε ένα token. Για τους σκοπούς των γραμματικών ορισμών, τα tokens είναι το ίδιο με τους κανόνες.

  • "text", 'text': Το κείμενο σε μονά ή διπλά εισαγωγικά πρέπει να ταιριάζει κυριολεκτικά (χωρίς τα εισαγωγικά). Ο τύπος του εισαγωγικού επιλέγεται ανάλογα με τη σημασία του text:

    • 'if': Ένα όνομα σε μονά εισαγωγικά υποδηλώνει μια keyword.

    • "case": Ένα όνομα σε διπλά εισαγωγικά υποδηλώνει ένα soft-keyword.

    • '@': Ένα σύμβολο που δεν περιέχει γράμμα σε μονά εισαγωγικά υποδηλώνει ένα OP token, δηλαδή, ένα delimiter ή operator.

  • e1 e2: Τα στοιχεία που χωρίζονται μόνο με κενό υποδηλώνουν μια ακολουθία. Εδώ, το e1 πρέπει να ακολουθείται από το e2.

  • e1 | e2: Χρησιμοποιείται μια κάθετη γραμμή για τον διαχωρισμό των εναλλακτικών λύσεων. Υποδηλώνει την «διατεταγμένη επιλογή» του PEG: εάν το e1 ταιριάζει, το e2 δεν λαμβάνεται υπόψη. Στις παραδοσιακές γραμματικές του PEG, αυτό γράφεται ως κάθετος, /, αντί για κάθετη γραμμή. Δείτε το PEP 617 για περισσότερες πληροφορίες και λεπτομέρειες.

  • e*: Ένας αστερίσκος σημαίνει μηδέν ή περισσότερες επαναλήψεις του προηγούμενοι στοιχείου.

  • e+: Ομοίως, ένα συν σημαίνει μία ή περισσότερες επαναλήψεις.

  • [e]: Μια φράση που περικλείεται σε αγκύλες σημαίνει μηδέν ή μία εμφάνιση. Με άλλα λόγια, η φράση που περικλείεται είναι προαιρετική.

  • e?: Ένα ερωτηματικό έχει ακριβώς την ίδια σημασία με τις αγκύλες: το προηγούμενο στοιχείο είναι προαιρετικό.

  • (e): Οι παρενθέσεις χρησιμοποιούνται για ομαδοποίηση.

The following notation is only used in lexical definitions.

  • "a"..."z": Two literal characters separated by three dots mean a choice of any single character in the given (inclusive) range of ASCII characters.

  • <...>: A phrase between angular brackets gives an informal description of the matched symbol (for example, <any ASCII character except "\">), or an abbreviation that is defined in nearby text (for example, <Lu>).

Some definitions also use lookaheads, which indicate that an element must (or must not) match at a given position, but without consuming any input:

  • &e: a positive lookahead (that is, e is required to match)

  • !e: a negative lookahead (that is, e is required not to match)

Οι μοναδιαίοι τελεστές (*, +, ?) συνδέονται όσο το δυνατόν πιο σφιχτά∙ η κάθετη γραμμή (|) συνδέεται πιο χαλαρά.

Το κενό έχει νόημα μόνο για τον διαχωρισμό των διακριτικών.

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

literal: stringliteral | bytesliteral
         | integer | floatnumber | imagnumber

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

literal:
   | stringliteral
   | bytesliteral
   | integer
   | floatnumber
   | imagnumber

Αυτό δεν σημαίνει ότι υπάρχει μια κενή πρώτη εναλλακτική λύση.

1.2.1. Λεξικοί και Συντακτικοί ορισμοί

Υπάρχει κάποια διαφορά μεταξύ της λεξικής και της συντακτικής ανάλυσης: ο lexical analyzer λειτουργεί στους μεμονωμένους χαρακτήρες της πηγής εισόδου, ενώ ο αναλυτής (συντακτικός αναλυτής) λειτουργεί στη ροή των tokens που δημιουργούνται από τη λεξική ανάλυση. Ωστόσο, σε ορισμένες περιπτώσεις το ακριβές όριο μεταξύ των δύο φάσεων είναι μια λεπτομέρεια υλοποίησης της CPython.

Η πρακτική διαφορά μεταξύ των δύο είναι ότι στους λεξιλογικούς ορισμούς, όλα τα κενά είναι σημαντικά. Ο λεξικός αναλυτής discards όλα τα κενά που δεν μετατρέπονται σε διακριτικά όπως token.INDENT ή NEWLINE. Οι συντακτικοί ορισμοί χρησιμοποιούν στη συνέχεια αυτά τα διακριτικά, αντί για τους χαρακτήρες προέλευσης.

Αυτή η τεκμηρίωση χρησιμοποιεί την ίδια γραμματική BNF και για τα δύο στυλ ορισμών. Όλες οι χρήσεις του BNF στο επόμενο κεφάλαιο (Lexical analysis) είναι λεξιλογικοί ορισμοί∙ οι χρήσεις στα επόμενα κεφάλαια είναι συντακτικοί ορισμοί.