7. Είσοδος και Έξοδος

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

7.1. Ομορφότερη Μορφοποίηση Εξόδου

So far we’ve encountered two ways of writing values: expression statements and the print() function. (A third way is using the write() method of file objects; the standard output file can be referenced as sys.stdout. See the Library Reference for more information on this.)

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

  • Για να χρησιμοποιήσετε formatted string literals, ξεκινήστε μια συμβολοσειρά με f or F πριν από το αρχικό εισαγωγικό ή το τριπλό εισαγωγικό. Μέσα σε αυτήν την συμβολοσειρά, μπορείτε να γράψετε μια έκφραση Python μεταξύ χαρακτήρων { και } που μπορεί να αναφέρεται σε μεταβλητές ή κυριολεκτικές τιμές.

    >>> year = 2016
    >>> event = 'Referendum'
    >>> f'Results of the {year} {event}'
    'Results of the 2016 Referendum'
    
  • The str.format() method of strings requires more manual effort. You’ll still use { and } to mark where a variable will be substituted and can provide detailed formatting directives, but you’ll also need to provide the information to be formatted.

    >>> yes_votes = 42_572_654
    >>> no_votes = 43_132_495
    >>> percentage = yes_votes / (yes_votes + no_votes)
    >>> '{:-9} YES votes  {:2.2%}'.format(yes_votes, percentage)
    ' 42572654 YES votes  49.67%'
    
  • Τέλος, μπορείτε να κάνετε μόνοι σας όλο τον χειρισμό συμβολοσειράς χρησιμοποιώντας λειτουργίες slicing και συνένωσης συμβολοσειρών για να δημιουργήσετε οποιαδήποτε διάταξη μπορείτε να φανταστείτε. Ο τύπος συμβολοσειράς έχει ορισμένες μεθόδους που εκτελούν χρήσιμες λειτουργίες για την προσθήκη συμβολοσειρών σε ένα δεδομένο πλάτος στήλης.

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

Η συνάρτηση str() προορίζεται να επιστρέφει αναπαραστάσεις τιμών που είναι αρκετά αναγνώσιμες από τον άνθρωπο, ενώ το repr() προορίζεται για τη δημιουργία αναπαραστάσεων που μπορούν να διαβαστούν από τον διερμηνέα (ή θα επιβάλουν ένα SyntaxError αν δεν υπάρχει ισοδύναμη σύνταξη). Για αντικείμενα που δεν έχουν συγκεκριμένη αναπαράσταση για ανθρώπινη κατανάλωση, η str() θα επιστρέψει την ίδια τιμή με το repr(). Πολλές τιμές, όπως αριθμοί ή δομές όπως λίστες και λεξικά, έχουν την ίδια αναπαράσταση χρησιμοποιώντας οποιαδήποτε συνάρτηση. Τα strings, συγκεκριμένα, έχουν δύο διακριτές παραστάσεις.

Μερικά παραδείγματα:

>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
>>> print(s)
The value of x is 32.5, and y is 40000...
>>> # The repr() of a string adds string quotes and backslashes:
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, world\n'
>>> # The argument to repr() may be any Python object:
... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"

Το module string περιέχει μια κλάση Template που προσφέρει έναν ακόμη τρόπο αντικατάστασης τιμών σε συμβολοσειρές, χρησιμοποιώντας placeholders όπως $x και αντικαθιστώντας τις με τιμές από ένα λεξικό, αλλά προσφέρει πολύ λιγότερο έλεγχο της μορφοποίησης.

7.1.1. Μορφοποιημένα String Literals

Τα Formatted string literals (ονομάζονται επίσης f-strings για συντομία) σας επιτρέπουν να συμπεριλάβετε την τιμή των εκφράσεων Python μέσα σε μια συμβολοσειρά, θέτοντας πρόθεμα στη συμβολοσειρά με f ή F και γράφοντας εκφράσεις ως {expression}.

Ένας προαιρετικός αναθέτης (specifier) μορφής μπορεί να ακολουθεί την έκφραση. Αυτό επιτρέπει μεγαλύτερο έλεγχο στον τρόπο μορφοποίησης της τιμής. Το παρακάτω παράδειγμα στρογγυλοποιεί το pi σε τρία ψηφία μετά το δεκαδικό:

>>> import math
>>> print(f'The value of pi is approximately {math.pi:.3f}.')
The value of pi is approximately 3.142.

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

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
...     print(f'{name:10} ==> {phone:10d}')
...
Sjoerd     ==>       4127
Jack       ==>       4098
Dcab       ==>       7678

Μπορούν να χρησιμοποιηθούν άλλοι τροποποιητές για την μετατροπή της τιμής πριν τη μορφοποίηση της. Το '!a' ισχύει για ascii(), το '!s' ισχύει για str(), και το '!r' ισχύει για repr():

>>> animals = 'eels'
>>> print(f'My hovercraft is full of {animals}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of 'eels'.

For a reference on these format specifications, see the reference guide for the Format Specification Mini-Language.

7.1.2. Η μέθοδος String format()

Η βασική χρήση της μεθόδου str.format() μοιάζει με αυτό:

>>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"

Οι αγκύλες και οι χαρακτήρες μέσα σε αυτές (που ονομάζονται πεδία μορφής) αντικαθίστανται με τα αντικείμενα που μεταβιβάζονται στη μέθοδο str.format(). Ένας αριθμός στις αγκύλες μπορεί να χρησιμοποιηθεί για να αναφέρεται στη θέση του αντικειμένου που μεταβιβάζεται στη μέθοδο str.format().

>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam

Εάν χρησιμοποιούνται keyword ορίσματα στη μέθοδο str.format(), οι τιμές τους αναφέρονται χρησιμοποιώντας το όνομα του ορίσματος.

>>> print('This {food} is {adjective}.'.format(
...       food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.

Τα ορίσματα θέσης και λέξης-κλειδιού μπορούν να συνδυαστούν αυθαίρετα:

>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',
                                                       other='Georg'))
The story of Bill, Manfred, and Georg.

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

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
...       'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

This could also be done by passing the table as keyword arguments with the “**” notation.

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

This is particularly useful in combination with the built-in function vars(), which returns a dictionary containing all local variables.

As an example, the following lines produce a tidily-aligned set of columns giving integers and their squares and cubes:

>>> for x in range(1, 11):
...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

Για μια πλήρη επισκόπηση της μορφοποίησης συμβολοσειρών με str.format(), δείτε Format String Syntax.

7.1.3. Χειροκίνητη Μορφοποίηση Συμβολοσειρών

Ακολουθεί ο ίδιος πίνακας τετραγώνων και κύβων, μορφοποιημένος χειροκίνητα:

>>> for x in range(1, 11):
...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
...     # Note use of 'end' on previous line
...     print(repr(x*x*x).rjust(4))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

(Σημειώστε ότι το ένα κενό μεταξύ κάθε στήλης προστέθηκε με τον τρόπο που λειτουργεί το print(): προσθέτει πάντα κενά μεταξύ των ορισμάτων του.)

Η μέθοδος str.rjust() των αντικειμένων συμβολοσειράς τοποθετεί δεξιά μια συμβολοσειρά σε ένα πεδίο δεδομένου πλάτους συμπληρώνοντας την με κενά στα αριστερά. Υπάρχουν παρόμοιες μέθοδοι str.ljust() και str.center(). Αυτές οι μέθοδοι δεν γράφουν τίποτα, απλώς επιστρέφουν μια συμβολοσειρά. Εάν η συμβολοσειρά εισόδου είναι πολύ μεγάλη, δεν την περικόπτουν, αλλά την επιστρέφουν αμετάβλητη· αυτό θα μπερδέψει τη διάταξη της στήλης σας, αλλά αυτό είναι συνήθως καλύτερο από την εναλλακτική, που θα ήταν ψέματα για μια τιμή. (Αν θέλετε πραγματικά περικοπή, μπορείτε πάντα να προσθέσετε μια λειτουργία slice, όπως στο x.ljust(n)[:n].)

Υπάρχει μια άλλη μέθοδος, η str.zfill(), η οποία συμπληρώνει μια αριθμητική συμβολοσειρά στα αριστερά με μηδενικά. Καταλαβαίνει τα σύμβολα συν και πλην:

>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'

7.1.4. Παλιά μορφοποίηση συμβολοσειράς

The % operator (modulo) can also be used for string formatting. Given 'string' % values, instances of % in string are replaced with zero or more elements of values. This operation is commonly known as string interpolation. For example:

>>> import math
>>> print('The value of pi is approximately %5.3f.' % math.pi)
The value of pi is approximately 3.142.

Περισσότερες πληροφορίες μπορείτε να βρείτε στην ενότητα printf-style String Formatting.

7.2. Ανάγνωση και Εγγραφή Αρχείων

Η open() επιστρέφει ένα file object, και χρησιμοποιείται πιο συχνά με δύο ορίσματα θέσης και ένα όρισμα λέξης-κλειδιού: open(filename, mode, encoding=None)

>>> f = open('workfile', 'w', encoding="utf-8")

Το πρώτο όρισμα είναι μια συμβολοσειρά που περιέχει το όνομα αρχείου. Το δεύτερο όρισμα είναι μια άλλη συμβολοσειρά που περιέχει μερικούς χαρακτήρες που περιγράφουν τον τρόπο με τον οποίο θα χρησιμοποιηθεί το αρχείο. Η mode μπορεί να είναι 'r' όταν το αρχείο θα είναι μόνο για διάβασμα, 'w' μόνο για εγγραφή (ένα υπάρχον αρχείο με το ίδιο όνομα θα διαγραφεί) και το 'a' ανοίγει το αρχείο για προσάρτηση· οποιαδήποτε δεδομένα γράφονται στο αρχείο και προστίθενται αυτόματα στο τέλος. Το 'r+' ανοίγει το αρχείο τόσο για ανάγνωση όσο και για γραφή. Το όρισμα mode είναι προαιρετικό· το 'r' θα θεωρείται εάν παραληφθεί.

Κανονικά, τα αρχεία ανοίγουν σε text mode, που σημαίνει ότι διαβάζετε και γράφετε συμβολοσειρές από και προς το αρχείο, οι οποίες κωδικοποιούνται σε μια συγκεκριμένη κωδικοποίηση. Εάν δεν έχει καθοριστεί η κωδικοποιήση, η προεπιλογή είναι εξαρτώμενη από την πλατφόρμα (δείτε open()). Επειδή το UTF-8 είναι το σύγχρονο de-facto standard, encoding="utf-8" συνίσταται εκτός εάν γνωρίζετε ότι πρέπει να χρησιμοποιήσετε διαφορετική κωδικοποίηση. Η προσθήκη ενός 'b' στη λειτουργία ανοίγει το αρχείο σε binary mode. Τα δεδομένα δυαδικής λειτουργίας διαβάζονται και γράφονται ως αντικείμενα bytes. Δεν μπορείτε να καθορίσετε κωδικοποίηση όταν ανοίγετε αρχείο σε δυαδική λειτουργία.

Στη λειτουργία κειμένου, η προεπιλογή (default) κατά την ανάγνωση είναι να μετατρέψετε τις καταλήξεις γραμμών για συγκεκριμένη πλατφόρμα (\n στο Unix, \r\n στα Windows) σε μόνο \n. Όταν γράφετε σε λειτουργία κειμένου, η προεπιλογή είναι να μετατρέπονται οι εμφανίσεις \n σε καταλήξεις γραμμών για συγκεκριμένη πλατφόρμα. Αυτή η παρασκηνιακή τροποποίηση στα δεδομένα αρχείων είναι καλή για αρχεία κειμένου, αλλά θα καταστρέψει δυαδικά δεδομένα όπως αυτό σε αρχεία JPEG ή EXE. Να είστε πολύ προσεκτικοί να χρησιμοποιείτε τη δυαδική λειτουργία όταν διαβάζετε και γράφετε τέτοια αρχεία.

Είναι καλή πρακτική να χρησιμοποιείτε το keyword with όταν ασχολούμαστε με αντικείμενα αρχείου. Το πλεονέκτημα είναι ότι το αρχείο κλείνει σωστά μετά την ολοκλήρωση της εκτέλεσής του, ακόμα κι αν κάποια στιγμή προκύψει εξαίρεση. Χρησιμοποιώντας το with είναι επίσης πολύ πιο σύντομο από την σύνταξη ισοδύναμου try-finally blocks:

>>> with open('workfile', encoding="utf-8") as f:
...     read_data = f.read()

>>> # We can check that the file has been automatically closed.
>>> f.closed
True

Εάν δεν χρησιμοποιείτε τη keyword with, τότε θα πρέπει να καλείτε τη f.close() για να κλείσετε το αρχείο και να ελευθερώσετε αμέσως τυχόν πόρους συστήματος που χρησιμοποιούνται από αυτό.

Προειδοποίηση

Η κλήση του f.write() χωρίς τη χρήση της keyword with ή η κλήση του f.close() μπορεί να οδηγήσει στα ορίσματα του f.write() να μην εγγραφεί πλήρως στο δίσκο, ακόμα και αν το πρόγραμμα εξέλθει με επιτυχία.

Μετά το κλείσιμο ενός αντικειμένου αρχείου, είτε μια δήλωση with είτε καλώντας f.close(), οι προσπάθειες χρήσης του αντικειμένου αρχείου θα αποτύχουν αυτόματα.

>>> f.close()
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.

7.2.1. Μέθοδοι Αντικειμένων Αρχείων

Τα υπόλοιπα παραδείγματα σε αυτήν την ενότητα θα υποθέσουν ότι ένα αντικείμενο αρχείου που ονομάζεται f έχει ήδη δημιουργηθεί.

Για να διαβάσετε τα περιεχόμενα ενός αρχείου, καλέστε το f.read(size), το οποίο διαβάζει κάποια ποσότητα δεδομένων και την επιστρέφει ως συμβολοσειρά (σε λειτουργία κειμένου) ή ως αντικείμενο bytes (σε δυαδική λειτουργία). Το size είναι προαιρετικό αριθμητικό όρισμα. Όταν το size παραλείπεται ή είναι αρνητικό, ολόκληρο το περιεχόμενο του αρχείου θα διαβαστεί και θα επιστραφεί∙ είναι δικό σας πρόβλημα εάν το αρχείο είναι διπλάσιο από τη μνήμη του υπολογιστή σας. Διαφορετικά, διαβάζονται και επιστρέφονται το πολύ size χαρακτήρες (σε λειτουργία κειμένου) ή byte size (σε δυαδική λειτουργία). Εάν έχει φτάσει το τέλος του αρχείου, το f.read() θα επιστρέψει μια κενή συμβολοσειρά ('').

>>> f.read()
'This is the entire file.\n'
>>> f.read()
''

Το f.readline() διαβάζει μία γραμμή από το αρχείο· ένας χαρακτήρας νέας γραμμής (\n) παραμένει στο τέλος της συμβολοσειράς, και παραλείπεται μόνο στην τελευταία γραμμή του αρχείου εάν το αρχείο δεν τελειώνει σε μια νέα γραμμή. Αυτό καθιστά την τιμή επιστροφής σαφή· εάν το f.readline() επιστρέφει μια κενή συμβολοσειρά, έχει φτάσει στο τέλος του αρχείου, ενώ μια κενή γραμμή αντιπροσωπεύεται από '\n', μια συμβολοσειρά που περιέχει μόνο μία νέα γραμμή.

>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''

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

>>> for line in f:
...     print(line, end='')
...
This is the first line of the file.
Second line of the file

Εάν θέλετε να διαβάσετε όλες τις γραμμές ενός αρχείου σε μια λίστα, μπορείτε επίσης να χρησιμοποιήσετε το list(f) ή f.readlines().

Το f.write(string) γράφει τα περιεχόμενα του string στο αρχείο, επιστρέφοντας τον αριθμό των χαρακτήρων που γράφτηκαν.

>>> f.write('This is a test\n')
15

Άλλοι τύποι αντικειμένων πρέπει να μετατραπούν – είτε σε μια συμβολοσειρά (σε λειτουργία κειμένου) ή σε ένα αντικείμενο bytes (σε δυαδική λειτουργία) – πριν τα γράψετε:

>>> value = ('the answer', 42)
>>> s = str(value)  # convert the tuple to string
>>> f.write(s)
18

Το f.tell() επιστρέφει έναν ακέραιο που δίνει την τρέχουσα θέση του αντικειμένου αρχείου στο αρχείο που αντιπροσωπεύεται ως αριθμό byte από την αρχή του αρχείου όταν βρίσκεται σε δυαδική λειτουργία και έναν αδιαφανή αριθμό όταν βρίσκεται σε λειτουργία κειμένου.

Για να αλλάξετε τη θέση του αντικειμένου, χρησιμοποιήστε το f.seek(offset, whence). Η θέση υπολογίζεται από την προσθήκη offset σε ένα σημείο αναφοράς· το σημείο αναφοράς επιλέγεται από το όρισμα whence. Μια 0 τιμή whence μετρά από την αρχή του αρχείο το 1 χρησιμοποιεί την τρέχουσα θέση αρχείου και το 2 χρησιμοποιεί το τέλος του αρχείου ως σημείο αναφοράς. Το whence μπορεί να παραληφθεί και να οριστεί από προεπιλογή 0, χρησιμοποιώντας την αρχή του αρχείου ως σημείο αναφοράς.

>>> f = open('workfile', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5)      # Go to the 6th byte in the file
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2)  # Go to the 3rd byte before the end
13
>>> f.read(1)
b'd'

Σε αρχεία κειμένου (αυτά που ανοίγουν χωρίς b στη λειτουργία string), επιτρέπονται μόνο αναζητήσεις σε σχέση με την αρχή του αρχείου (η εξαίρεση είναι η αναζήτηση μέχρι το ίδιο το αρχείο που τελειώνει με seek(0, 2)) και οι μόνες έγκυρες τιμές offset είναι αυτές που επιστρέφονται από το f.tell(), ή μηδέν. Οποιαδήποτε άλλη τιμή offset παράγει απροσδιόριστη συμπεριφορά.

File objects have some additional methods, such as isatty() and truncate() which are less frequently used; consult the Library Reference for a complete guide to file objects.

7.2.2. Αποθήκευση δομημένων δεδομένων με json

Strings can easily be written to and read from a file. Numbers take a bit more effort, since the read() method only returns strings, which will have to be passed to a function like int(), which takes a string like '123' and returns its numeric value 123. When you want to save more complex data types like nested lists and dictionaries, parsing and serializing by hand becomes complicated.

Rather than having users constantly writing and debugging code to save complicated data types to files, Python allows you to use the popular data interchange format called JSON (JavaScript Object Notation). The standard module called json can take Python data hierarchies, and convert them to string representations; this process is called serializing. Reconstructing the data from the string representation is called deserializing. Between serializing and deserializing, the string representing the object may have been stored in a file or data, or sent over a network connection to some distant machine.

Σημείωση

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

Εάν έχετε ένα αντικείμενο x, μπορείτε να δείτε την αναπαράσταση συμβολοσειράς JSON με μια απλή γραμμή κώδικα:

>>> import json
>>> x = [1, 'simple', 'list']
>>> json.dumps(x)
'[1, "simple", "list"]'

Μια άλλη παραλλαγή της συνάρτησης dumps(), που ονομάζεται dump(), απλώς σειριοποιεί το αντικείμενο σε ένα text file. Έτσι, εάν το f είναι ένα αντικείμενο text file που ανοίγει για εγγραφή, μπορούμε να κάνουμε αυτό:

json.dump(x, f)

Για να αποκωδικοποιήσετε ξανά το αντικείμενο, εάν το f είναι ένα αντικείμενο binary file ή text file που έχει ανοίξει για ανάγνωση:

x = json.load(f)

Σημείωση

Τα αρχεία JSON πρέπει να είναι κωδικοποιημένα σε UTF-8. Χρησιμοποιήστε το encoding="utf-8" όταν ανοίγετε το αρχείο JSON ως text file τόσο για ανάγνωση όσο και για εγγραφή.

Αυτή η απλή τεχνική σειριοποίησης μπορεί να χειριστεί λίστες και λεξικά, άλλα η σειριοποίηση αυθαίρετων στιγμιοτύπων κλάσεων σε JSON απαιτεί λίγη επιπλέον προσπάθεια. Η αναφορά για το module json περιέχει μια εξήγηση για αυτό.

Δείτε επίσης

pickle - το pickle module

Σε αντίθεση με το JSON, το pickle είναι ένα πρωτόκολλο που επιτρέπει τη σειριοποίηση αυθαίρετα πολύπλοκων αντικειμένων Python. Ως εκ τούτου, είναι συγκεκριμένο για την Python και δεν μπορεί να χρησιμοποιηθεί για επικοινωνία με εφαρμογές γραμμένες σε άλλες γλώσσες. Είναι επίσης ανασφαλές από προεπιλογή: η αποσειριοποίηση pickle δεδομένων που προέρχονται από μια μη αξιόπιστη πηγή μπορεί να εκτελέσει αυθαίρετο κώδικα, εάν τα δεδομένα έχουν δημιουργηθεί από έναν έμπειρο εισβολέα.