7.Είσοδος και Έξοδος¶
Υπάρχουν διάφοροι τρόποι για να παρουσιάσετε τα αποτελέσματα ενός προγράμματος· τα δεδομένα μπορούν να εκτυπωθούν σε μορφή αναγνώσιμη από τον άνθρωπο ή να εγγραφούν σε ένα αρχείο για μελλοντική χρήση. Αυτό το κεφάλαιο θα συζητήσει μερικές από τις δυνατότητες.
7.1.Ομορφότερη Μορφοποίηση Εξόδου¶
Μέχρι στιγμής έχουμε συναντήσει δύο τρόπους γραφής τιμών:expression statements και τη συνάρτησηprint()
. (Ένας τρίτος τρόπος είναι η χρήση της μεθόδουwrite()
των αντικειμένων αρχείων· το standard αρχείο εξόδου μπορεί να αναφέρεται ωςsys.stdout
. Δείτε την Αναφορά Βιβλιοθήκης για περισσότερες πληροφορίες σχετικά με αυτό.)
Συχνά θα θέλετε περισσότερο έλεγχο στη μορφοποίηση της εξόδου σας παρά απλώς να εκτυπώνετε τιμές διαχωρισμένες με διάστημα. Υπάρχουν διάφοροι τρόποι για να μορφοποιήσετε την έξοδο.
Για να χρησιμοποιήσετεformatted string literals, ξεκινήστε μια συμβολοσειρά με
f
orF
πριν από το αρχικό εισαγωγικό ή το τριπλό εισαγωγικό. Μέσα σε αυτήν την συμβολοσειρά, μπορείτε να γράψετε μια έκφραση Python μεταξύ χαρακτήρων{
και}
που μπορεί να αναφέρεται σε μεταβλητές ή κυριολεκτικές τιμές.>>>year=2016>>>event='Referendum'>>>f'Results of the{year}{event}''Results of the 2016 Referendum'
Η μέθοδος
str.format()
των συμβολοσειρών απαιτεί περισσότερη μη χειροκίνητη προσπάθεια. Θα εξακολουθείτε να χρησιμοποιείτε τα{
και}
για να επισημάνετε που θα αντικατασταθεί μια μεταβλητή και μπορεί να παρέχει λεπτομερείς οδηγίες μορφοποίησης, αλλά θα χρειαστεί επίσης να παρέχετε τις πληροφορίες που θα μορφοποιήσετε. Στο παρακάτω μπλοκ κώδικα υπάρχουν δύο παραδείγματα για τον τρόπο μορφοποίησης μεταβλητών:>>>yes_votes=42_572_654>>>total_votes=85_705_149>>>percentage=yes_votes/total_votes>>>'{:-9} YES votes{:2.2%}'.format(yes_votes,percentage)' 42572654 YES votes 49.67%'
Παρατηρήστε πως τα
yes_votes
συμπληρώνονται με κενά και αρνητικό πρόσημο μόνο για αρνητικούς αριθμούς. Το παράδειγμα εκτυπώνει επίσης τοpercentage
πολλαπλασιασμένο επί 100, με 2 δεκαδικά ψηφία και ακολουθούμενο από ένα σύμβολο ποσοστού (δείτε τοFormat Specification Mini-Language για λεπτομέρειες).Τέλος, μπορείτε να κάνετε μόνοι σας όλο τον χειρισμό συμβολοσειράς χρησιμοποιώντας λειτουργίες 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'))"
Το modulestring
περιέχει μια κλάσηTemplate
που προσφέρει έναν ακόμη τρόπο αντικατάστασης τιμών σε συμβολοσειρές, χρησιμοποιώντας placeholders όπως$x
και αντικαθιστώντας τις με τιμές από ένα λεξικό, αλλά προσφέρει πολύ λιγότερο έλεγχο της μορφοποίησης.
7.1.1.Μορφοποιημένα String Literals¶
ΤαFormatted string literals (ονομάζονται επίσης f-strings για συντομία) σας επιτρέπουν να συμπεριλάβετε την τιμή των εκφράσεων Python μέσα σε μια συμβολοσειρά, θέτοντας πρόθεμα στη συμβολοσειρά μεf
ήF
και γράφοντας εκφράσεις ως{expression}
.
Ένας προαιρετικός αναθέτης (specifier) μορφής μπορεί να ακολουθεί την έκφραση. Αυτό επιτρέπει μεγαλύτερο έλεγχο στον τρόπο μορφοποίησης της τιμής. Το παρακάτω παράδειγμα στρογγυλοποιεί το pi σε τρία ψηφία μετά το δεκαδικό:
>>>importmath>>>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}>>>forname,phoneintable.items():...print(f'{name:10} ==>{phone:10d}')...Sjoerd ==> 4127Jack ==> 4098Dcab ==> 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'.
Ο αναθέτης (specifier)=
μπορεί να χρησιμοποιηθεί για να επεκτείνει μια έκφραση στο κείμενο της έκφρασης, ένα σύμβολο ίσο, και μετά την αναπαράσταση της αξιολογούμενης έκφρασης:
>>>bugs='roaches'>>>count=13>>>area='living room'>>>print(f'Debugging{bugs=}{count=}{area=}')Debugging bugs='roaches' count=13 area='living room'
Δείτε τοself-documenting expressions για περισσότερες πληροφορίες σχετικά με τον αναθέτη (specifier)=
. Για αναφορά σε αυτές τις προδιαγραφές μορφής, ανατρέξτε στον οδηγό αναφοράς για το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
Αυτό θα μπορούσε επίσης να γίνει περνώντας το λεξικόtable
ως ορίσματα λέξεων-κλειδιών με την σημείωση**
.
>>>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
Αυτό είναι ιδιαίτερα χρήσιμο σε συνδυασμό με την ενσωματωμένη (built-in) συνάρτησηvars()
, η οποία επιστρέφει ένα λεξικό που περιέχει όλες τις τοπικές μεταβλητές:
>>>table={k:str(v)fork,vinvars().items()}>>>message=" ".join([f'{k}: '+'{'+k+'};'forkintable.keys()])>>>print(message.format(**table))__name__: __main__; __doc__: None; __package__: None; __loader__: ...
Για παράδειγμα, οι ακόλουθες γραμμές παράγουν ένα τακτοποιημένο σύνολο στηλών που δίνουν ακέραιους αριθμούς και τα τετράγωνα και τους κύβους τους:
>>>forxinrange(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 72910 100 1000
Για μια πλήρη επισκόπηση της μορφοποίησης συμβολοσειρών μεstr.format()
, δείτεFormat String Syntax.
7.1.3.Χειροκίνητη Μορφοποίηση Συμβολοσειρών¶
Ακολουθεί ο ίδιος πίνακας τετραγώνων και κύβων, μορφοποιημένος χειροκίνητα:
>>>forxinrange(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 72910 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.Παλιά μορφοποίηση συμβολοσειράς¶
Ο τελεστής % (modulo) μπορεί επίσης να χρησιμοποιηθεί για τη μορφοποίηση συμβολοσειρών. Δεδομένων των τιμώνformat%values
(όπουformat είναι μια συμβολοσειρά), οι προδιαγραφές μετατροπής%
σεformat αντικαθίστανται με μηδέν ή περισσότερα στοιχείατιμών. Αυτή η λειτουργία είναι κοινώς γνωστή ως παρεμβολή συμβολοσειρών. Για παράδειγμα:
>>>importmath>>>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
. Να είστε πολύ προσεκτικοί να χρησιμοποιείτε τη δυαδική λειτουργία όταν διαβάζετε και γράφετε τέτοια αρχεία.
Είναι καλή πρακτική να χρησιμοποιείτε το keywordwith
όταν ασχολούμαστε με αντικείμενα αρχείου. Το πλεονέκτημα είναι ότι το αρχείο κλείνει σωστά μετά την ολοκλήρωση της εκτέλεσής του, ακόμα κι αν κάποια στιγμή προκύψει εξαίρεση. Χρησιμοποιώντας τοwith
είναι επίσης πολύ πιο σύντομο από την σύνταξη ισοδύναμουtry
-finally
blocks:
>>>withopen('workfile',encoding="utf-8")asf:...read_data=f.read()>>># We can check that the file has been automatically closed.>>>f.closedTrue
Εάν δεν χρησιμοποιείτε τη keywordwith
, τότε θα πρέπει να καλείτε τηf.close()
για να κλείσετε το αρχείο και να ελευθερώσετε αμέσως τυχόν πόρους συστήματος που χρησιμοποιούνται από αυτό.
Προειδοποίηση
Η κλήση τουf.write()
χωρίς τη χρήση της keywordwith
ή η κλήση τουf.close()
μπορεί να οδηγήσει στα ορίσματα τουf.write()
να μην εγγραφεί πλήρως στο δίσκο, ακόμα και αν το πρόγραμμα εξέλθει με επιτυχία.
Μετά το κλείσιμο ενός αντικειμένου αρχείου, είτε μια δήλωσηwith
είτε καλώνταςf.close()
, οι προσπάθειες χρήσης του αντικειμένου αρχείου θα αποτύχουν αυτόματα.
>>>f.close()>>>f.read()Traceback (most recent call last): File"<stdin>", line1, in<module>ValueError:I/O operation on closed file.
7.2.1.Μέθοδοι Αντικειμένων Αρχείων¶
Τα υπόλοιπα παραδείγματα σε αυτήν την ενότητα θα υποθέσουν ότι ένα αντικείμενο αρχείου που ονομάζεταιf
έχει ήδη δημιουργηθεί.
Για να διαβάσετε τα περιεχόμενα ενός αρχείου, καλέστε τοf.read(size)
, το οποίο διαβάζει κάποια ποσότητα δεδομένων και την επιστρέφει ως συμβολοσειρά (σε λειτουργία κειμένου) ή ως αντικείμενο bytes (σε δυαδική λειτουργία). Τοsize είναι προαιρετικό αριθμητικό όρισμα. Όταν τοsize παραλείπεται ή είναι αρνητικό, ολόκληρο το περιεχόμενο του αρχείου θα διαβαστεί και θα επιστραφεί∙ είναι δικό σας πρόβλημα εάν το αρχείο είναι διπλάσιο από τη μνήμη του υπολογιστή σας. Διαφορετικά, διαβάζονται και επιστρέφονται το πολύsize χαρακτήρες (σε λειτουργία κειμένου) ή bytesize (σε δυαδική λειτουργία). Εάν έχει φτάσει το τέλος του αρχείου, το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 πάνω από το αντικείμενο του αρχείου. Αυτό είναι αποδοτικό στη μνήμη, γρήγορο και οδηγεί σε απλό κώδικα:
>>>forlineinf:...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 file5>>>f.read(1)b'5'>>>f.seek(-3,2)# Go to the 3rd byte before the end13>>>f.read(1)b'd'
Σε αρχεία κειμένου (αυτά που ανοίγουν χωρίςb
στη λειτουργία string), επιτρέπονται μόνο αναζητήσεις σε σχέση με την αρχή του αρχείου (η εξαίρεση είναι η αναζήτηση μέχρι το ίδιο το αρχείο που τελειώνει μεseek(0,2)
) και οι μόνες έγκυρες τιμέςoffset είναι αυτές που επιστρέφονται από τοf.tell()
, ή μηδέν. Οποιαδήποτε άλλη τιμήoffset παράγει απροσδιόριστη συμπεριφορά.
Τα αντικείμενα αρχείου έχουν ορισμένες πρόσθετες μεθόδους, όπωςisatty()
καιtruncate()
που χρησιμοποιούνται λιγότερο συχνά· συμβουλευτείτε την Αναφορά της Βιβλιοθήκης για έναν πλήρη οδηγό για τα αντικείμενα αρχείων.
7.2.2.Αποθήκευση δομημένων δεδομένων μεjson
¶
Οι συμβολοσειρές μπορούν εύκολα να γραφούν και να διαβαστούν από ένα αρχείο. Οι αριθμοί απαιτούν λίγο περισσότερη προσπάθεια, καθώς η μέθοδοςread()
επιστρέφει μόνο συμβολοσειρές, οι οποίες θα πρέπει να περάσουν μια συνάρτηση όπωςint()
, που παίρνει μια συμβολοσειρά όπως'123'
και επιστρέφει την αριθμητική της τιμή 123. Όταν θέλετε να αποθηκεύσετε πιο σύνθετους τύπους δεδομένων, όπως ένθετε λίστες και λεξικά, η ανάλυση και η σειριοποίηση με το χέρι γίνεται περίπλοκη.
Αντί να χρειάζεται οι χρήστες να γράφουν και να διορθώνουν συνεχώς κώδικα για να αποθηκεύουν πολύπλοκους τύπους δεδομένων σε αρχεία, η Python σας επιτρέπει να χρησιμοποιείτε τη δημοφιλή μορφή ανταλλαγής δεδομένων που ονομάζεταιJSON (JavaScript Object Notation). Το standard module που ονομάζεταιjson
μπορεί να λάβει ιεραρχίες δεδομένων Python, και να τις μετατρέψει σε αναπαραστάσεις συμβολοσειρών· αυτή η διαδικασία ονομάζεταιserializing.. Η ανασύνθεση των δεδομένων από την αναπαράσταση συμβολοσειράς ονομάζεταιdeserializing. Μεταξύ σειριοποίησης και αποσειριοποίησης, η συμβολοσειρά που αντιπροσωπεύει το αντικείμενο μπορεί να έχει αποθηκευτεί σε ένα αρχείο ή δεδομένα ή να έχει σταλεί μέσω μιας σύνδεσης δικτύου σε κάποιο απομακρυσμένο μηχάνημα.
Σημείωση
Η μορφή JSON χρησιμοποιείται συνήθως από σύγχρονες εφαρμογές για να επιτρέπει την ανταλλαγή δεδομένων. Πολλοί προγραμματιστές είναι ήδη εξοικειωμένοι με αυτήν, γεγονός που την καθιστά καλή επιλογή για διαλειτουργικότητα.
Εάν έχετε ένα αντικείμενοx
, μπορείτε να δείτε την αναπαράσταση συμβολοσειράς JSON με μια απλή γραμμή κώδικα:
>>>importjson>>>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 απαιτεί λίγη επιπλέον προσπάθεια. Η αναφορά για το modulejson
περιέχει μια εξήγηση για αυτό.
Δείτε επίσης
pickle
- το pickle module
Σε αντίθεση με τοJSON, τοpickle είναι ένα πρωτόκολλο που επιτρέπει τη σειριοποίηση αυθαίρετα πολύπλοκων αντικειμένων Python. Ως εκ τούτου, είναι συγκεκριμένο για την Python και δεν μπορεί να χρησιμοποιηθεί για επικοινωνία με εφαρμογές γραμμένες σε άλλες γλώσσες. Είναι επίσης ανασφαλές από προεπιλογή: η αποσειριοποίηση pickle δεδομένων που προέρχονται από μια μη αξιόπιστη πηγή μπορεί να εκτελέσει αυθαίρετο κώδικα, εάν τα δεδομένα έχουν δημιουργηθεί από έναν έμπειρο εισβολέα.