Τι είναι το __init__ στην Python; [With Examples]

Θέλετε να ξεκινήσετε με αντικειμενοστραφή σχεδιασμό στην Python; Κάντε τα πρώτα βήματα σήμερα μαθαίνοντας για τη μέθοδο __init__ της Python.

Σε αυτό το σεμινάριο, θα εξετάσουμε τα βασικά των κλάσεων και των αντικειμένων Python και, στη συνέχεια, θα προχωρήσουμε στην εκμάθηση της μεθόδου __init__.

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

  • Τι είναι οι μεταβλητές ή τα χαρακτηριστικά του στιγμιότυπου;
  • Πώς βοηθά η μέθοδος init στην προετοιμασία των χαρακτηριστικών του στιγμιότυπου;
  • Πώς μπορούμε να ορίσουμε προεπιλεγμένες τιμές για τα χαρακτηριστικά;
  • Πώς μπορούμε να χρησιμοποιήσουμε μεθόδους κλάσης ως κατασκευαστές για να δημιουργήσουμε αντικείμενα;

Ας αρχίσουμε.

Κλάσεις και αντικείμενα Python

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

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

👩‍🏫Παράδειγμα χρόνου! Ας δημιουργήσουμε μια κλάση Employee όπου κάθε αντικείμενο αυτής της κλάσης έχει τα ακόλουθα χαρακτηριστικά:

  • πλήρες_όνομα: το πλήρες όνομα του υπαλλήλου στη μορφή firstName lastName
  • emp_id: το αναγνωριστικό υπαλλήλου
  • τμήμα: το τμήμα στο οποίο ανήκουν
  • εμπειρία: ο αριθμός των ετών εμπειρίας που έχουν

Τι σημαίνει αυτό? 🤔

Κάθε μεμονωμένος εργαζόμενος θα είναι ένα παράδειγμα ή αντικείμενο της κατηγορίας Υπαλλήλων. Και κάθε αντικείμενο θα έχει τη δική του τιμή για το πλήρες_όνομα, το emp_id, το τμήμα και την εμπειρία.

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

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

class Employee:
    pass

Η χρήση του πάσου (ως κράτησης θέσης) μας βοηθά να αποφύγουμε σφάλματα κατά την εκτέλεση του σεναρίου.

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

employee_1 = Employee()

print(employee_1)
#Output: <__main__.Employee object at 0x00FEE7F0>

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

employee_1.full_name="Amy Bell"
employee_1.department="HR"

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

Κατανόηση του ρόλου της μεθόδου __init__ σε μια τάξη Python

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

  Κατασκευές στο Golang

Εάν έχετε προγραμματίσει σε μια γλώσσα όπως η C++, θα δείτε ότι η μέθοδος __init__ λειτουργεί παρόμοια με τους κατασκευαστές.

Καθορισμός της μεθόδου __init__

Ας προσθέσουμε τη μέθοδο __init__ στην κλάση Employee:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience

Η παράμετρος self αναφέρεται στην παρουσία της κλάσης και το self.attribute αρχικοποιεί το χαρακτηριστικό instance στην τιμή στη δεξιά πλευρά.

Μπορούμε τώρα να δημιουργήσουμε αντικείμενα όπως:

employee_2 = Employee('Bella Joy','M007','Marketing',3)
print(employee_2)
# Output: <__main__.Employee object at 0x017F88B0>

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

 def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Προσθέτοντας το __repr__ στην κλάση Employee, έχουμε:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Τώρα τα αντικείμενα υπαλλήλου έχουν μια χρήσιμη συμβολοσειρά αναπαράστασης:

print(employee_2)
# Output: Bella Joy,M007 from Marketing with 3 years of experience.

Μερικές Συμβάσεις

Πριν προχωρήσουμε παρακάτω, ακολουθούν μερικές σημειώσεις:

  • Χρησιμοποιήσαμε τον εαυτό ως την πρώτη παράμετρο στη μέθοδο __init__ για να αναφερθούμε στην ίδια την παρουσία της κλάσης και χρησιμοποιήσαμε self.attribute_name για να αρχικοποιήσουμε τα διάφορα χαρακτηριστικά. Η χρήση του εαυτού είναι η προτιμώμενη σύμβαση (μπορείτε ωστόσο να χρησιμοποιήσετε οποιοδήποτε άλλο όνομα).
  • Όταν ορίζουμε τη μέθοδο __init__, ορίζουμε τα ονόματα των παραμέτρων στους ορισμούς __init__ ώστε να ταιριάζουν με τα ονόματα των χαρακτηριστικών. Αυτό βελτιώνει την αναγνωσιμότητα.

Πώς να προσθέσετε προεπιλεγμένες τιμές για χαρακτηριστικά

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

Προσπαθήστε να δημιουργήσετε ένα αντικείμενο της κλάσης Employee χωρίς να μεταβιβάσετε την τιμή για το χαρακτηριστικό experience:

employee_3 = Employee('Jake Lee','E001','Engineering')

Θα λάβετε το ακόλουθο σφάλμα:

Traceback (most recent call last):
  File "main.py", line 22, in <module>
    employee_3 = Employee('Jake Lee','E001','Engineering')
TypeError: __init__() missing 1 required positional argument: 'experience'

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

Εδώ παρέχουμε μια προεπιλεγμένη τιμή 0 για το χαρακτηριστικό experience:

class Employee:
    def __init__(self, full_name,emp_id,department,experience=0):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Το αντικείμενο working_3 δημιουργείται χωρίς τιμή για το χαρακτηριστικό experience. Η προεπιλεγμένη τιμή 0 χρησιμοποιείται για εμπειρία.

employee_3 = Employee('Jake Lee','E001','Engineering')
print(employee_3.experience)
# Output: 0

Εναλλακτικοί κατασκευαστές τάξης με χρήση μεθόδων τάξης

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

  Πώς να βρείτε τον αριθμό μοντέλου σε φορητό υπολογιστή

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

Οπότε τι κάνουμε;

Ας πάρουμε ένα παράδειγμα. Ας υποθέσουμε ότι έχουμε τιμές της μεταβλητής instance σε ένα λεξικό Python:

dict_fanny = {'name':'Fanny Walker','id':'H203','dept':'HR','exp':2}

Μπορούμε να πατήσουμε το λεξικό και να λάβουμε όλα τα χαρακτηριστικά όπως:

name = dict_fanny['name']
id = dict_fanny['id']
dept = dict_fanny['dept']
exp = dict_fanny['exp']

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

employee_4 = Employee(name, id, dept, exp)
print(employee_4)
# Output: Fanny Walker,H203 from HR with 2 years of experience.

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

Στην Python, μπορούμε να χρησιμοποιήσουμε μεθόδους κλάσεων ως κατασκευαστές για να δημιουργήσουμε αντικείμενα της κλάσης. Για να δημιουργήσουμε μια μέθοδο κλάσης χρησιμοποιούμε το @classmethod decorator.

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

    @classmethod
    def from_dict(cls,data_dict):
        full_name = data_dict['name']
        emp_id = data_dict['id']
        department = data_dict['dept']
        experience = data_dict['exp']
        return cls(full_name, emp_id, department, experience)

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

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

Έτσι, όταν καλούμε τη μέθοδο κλάσης from_dict() για να δημιουργήσουμε αντικείμενα, την καλούμε στην κλάση Employee:

emp_dict = {'name':'Tia Bell','id':'S270','dept':'Sales','exp':3}
employee_5 = Employee.from_dict(emp_dict)
print(employee_5)
# Output: Tia Bell,S270 from Sales with 3 years of experience.

Τώρα, αν έχουμε ένα λεξικό για καθέναν από τους n υπαλλήλους, μπορούμε να χρησιμοποιήσουμε τη μέθοδο κλάσης from_dict() ως κατασκευαστή για να δημιουργήσουμε στιγμιότυπα σε αντικείμενα—χωρίς να χρειάζεται να ανακτήσουμε τις τιμές της στιγμιαίας μεταβλητής από το λεξικό.

📝Μια σημείωση για τις μεταβλητές κλάσης

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

  Πώς να χρησιμοποιήσετε το Workflow Builder του Slack

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

Συχνές ερωτήσεις

1. Γιατί χρειάζεστε τη μέθοδο __init__ στην Python;

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

2. Μπορείτε να έχετε πολλαπλές μεθόδους __init__ σε μια κλάση Python;

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

3. Τι συμβαίνει εάν δεν ορίσετε τη μέθοδο __init__ σε μια κλάση;

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

4. Μπορείτε να έχετε προεπιλεγμένες τιμές για ορίσματα στη μέθοδο __init__;

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

5. Μπορείτε να τροποποιήσετε χαρακτηριστικά εκτός της μεθόδου __init__;

Ναι, μπορείτε πάντα να ενημερώσετε την τιμή ενός χαρακτηριστικού εκτός της μεθόδου __init__. Μπορείτε επίσης να προσθέσετε νέα χαρακτηριστικά δυναμικά σε μια παρουσία αφού δημιουργήσετε τη συγκεκριμένη παρουσία.

συμπέρασμα

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

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

Στη συνέχεια, μάθετε περισσότερα για το εάν __name__==’__main__’ στην Python.