Περισσότερα
Πώς λειτουργεί ο διακοσμητής @property;
Θα ήθελα να καταλάβω πώς λειτουργεί η ενσωματωμένη συνάρτηση property
. Αυτό που με μπερδεύει είναι ότι η property
μπορεί επίσης να χρησιμοποιηθεί ως διακοσμητής, αλλά δέχεται ορίσματα μόνο όταν χρησιμοποιείται ως ενσωματωμένη συνάρτηση και όχι όταν χρησιμοποιείται ως διακοσμητής.
Αυτό το παράδειγμα προέρχεται από την τεκμηρίωση:
class C(object):
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
Τα ορίσματα του property
'είναι τα getx
, setx
, delx
και μια συμβολοσειρά doc.
Στον παρακάτω κώδικα το property
χρησιμοποιείται ως διακοσμητής. Το αντικείμενό του είναι η συνάρτηση x
, αλλά στον παραπάνω κώδικα δεν υπάρχει θέση για συνάρτηση αντικειμένου στα ορίσματα.
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
Και, πώς δημιουργούνται οι διακοσμητές x.setter
και x.deleter
;
Έχω μπερδευτεί.
884
3
Η συνάρτηση
property()
επιστρέφει ένα ειδικό αντικείμενο περιγραφής:Είναι αυτό το αντικείμενο που έχει επιπλέον μεθόδους:
Αυτές λειτουργούν ως διακοσμητές επίσης. Επιστρέφουν ένα νέο αντικείμενο ιδιοκτησίας:
που είναι αντίγραφο του παλιού αντικειμένου, αλλά με μία από τις συναρτήσεις να έχει αντικατασταθεί.
Θυμηθείτε, ότι η σύνταξη
@decorator
είναι απλά συντακτική ζάχαρη- η σύνταξη:στην πραγματικότητα σημαίνει το ίδιο πράγμα με το
οπότε η συνάρτηση
foo
αντικαθίσταται από τηνproperty(foo)
, η οποία όπως είδαμε παραπάνω είναι ένα ειδικό αντικείμενο. Στη συνέχεια, όταν χρησιμοποιείτε την@foo.setter()
, αυτό που κάνετε είναι να καλείτε τη μέθοδοproperty().setter
που σας έδειξα παραπάνω, η οποία επιστρέφει ένα νέο αντίγραφο της ιδιότητας, αλλά αυτή τη φορά με τη συνάρτηση setter να έχει αντικατασταθεί με τη διακοσμημένη μέθοδο.Η ακόλουθη ακολουθία δημιουργεί επίσης μια πλήρη ιδιότητα, χρησιμοποιώντας αυτές τις μεθόδους διακοσμητή.
Πρώτα δημιουργούμε μερικές συναρτήσεις και ένα αντικείμενο
property
με μόνο έναν getter:Στη συνέχεια χρησιμοποιούμε τη μέθοδο
.setter()
για να προσθέσουμε έναν setter:Τέλος, προσθέτουμε έναν διαγραφέα με τη μέθοδο
.deleter()
:Τέλος, το αντικείμενο
property
ενεργεί ως αντικείμενο περιγραφής, οπότε διαθέτει τις μεθόδους.__get__()
,.__set__()
και.__delete__()
για να συνδεθεί με τη λήψη, τον ορισμό και τη διαγραφή χαρακτηριστικών της περίπτωσης:Το Descriptor Howto περιλαμβάνει μια καθαρή Python υλοποίηση δείγματος του τύπου
property()
:Η τεκμηρίωση λέει ότι είναι απλά μια συντόμευση για τη δημιουργία ιδιοτήτων μόνο για ανάγνωση. Έτσι
είναι ισοδύναμο με
Το πρώτο μέρος είναι απλό:
είναι το ίδιο με
property
με έναν απλό getter.Το επόμενο βήμα θα ήταν να επεκτείνουμε αυτή την ιδιότητα με έναν setter και έναν deleter. Και αυτό συμβαίνει με τις κατάλληλες μεθόδους:
επιστρέφει μια νέα ιδιότητα η οποία κληρονομεί τα πάντα από την παλιά
x
συν τον δεδομένο setter.Ο
x.deleter
λειτουργεί με τον ίδιο τρόπο.