PYTHON - ΜΑΘΗΜΑ 17 - OOP: ΕΙΔΙΚΕΣ ΜΕΘΟΔΟΙ ΚΛΑΣΕΩΝ - Μέρος 7 από 13 - Επανάληψη επί Aντικειμένου

preview_player
Показать описание
ΠΕΡΙΕΧΟΜΕΝΑ ΒΙΝΤΕΟ:
1. Ειδικές Μέθοδοι Κλάσεων
1.6 Επανάληψη επί Aντικειμένου
=========================
ΠΕΡΙΕΧΟΜΕΝΑ ΜΑΘΗΜΑΤΟΣ:
1. Ειδικές Μέθοδοι Κλάσεων
1.1 Μετατροπή σε Συμβολοσειρά
1.2 Σχεσιακοί Τελεστές
1.3 Διθέσιοι Τελεστές
1.4 Τελεστές Καταχώρησης
1.5 Μονοθέσιοι Τελεστές
1.6 Επανάληψη επί Aντικειμένου
1.7 Λειτουργία ως Συνάρτηση
1.8 Αναπαράσταση Αντικειμένου
1.9 Δημιουργία και Καταστροφή Αντικ/νου
2. Data Structures: Queue (Ουρά)
3. Game Project: WoW Part 2
4. Data Project: Refactoring Part 2
Рекомендации по теме
Комментарии
Автор

Καλησπέρα κύριε Ψούνη, μια ερώτηση πάνω στην επανάληψη. Παρατήρησα ότι στην άσκηση 9 αν βάλω και το
def __len__(self):
return 3

τρέχει η επανάληψη τα x, y, z και μετά βγάζει εις αεί το None. Που είναι το λάθος εδώ;

tolissr
Автор

Καλησπέρα! Μία ερώτηση σχετικά με την σύνδεση της __getitem__ και της __next__! Έστω ότι ορίζω την απλή κλάση

class MyIterator:
def __init__(self):
self.array = [1, 2, 3]

def __getitem__(self, item):
return self.array[item]

Στη συνέχεια δημιουργώ ένα αντικείμενο b = MyIterator() και δημιουργώ μία δομή επανάληψης

for i in b:

print(i)

και οι αριθμοί 1, 2, 3 τυπώνονται κανονικα.
Βάσει του τρόπου λειτουργία της for, στην αρχη της εκτέλεσης τρέχει η iter(b) ωστε να δημιουργήσει εναν iterator και στη συνεχεια γίνονται διαδοχικές κλήσεις της __next__, μέχρι την ολοκλήρωση του βρόχου.
1) Στην συγκεκριμενη περίπτωση που δεν εχει οριστεί __iter__ για την κλάση αυτή, η built-in iter() ενεργοποιεί καποια __iter__ από κάποια κλάση-πρόγονο της MyIterator ? Επίσης τρεχοντας την b = iter(b) δοκιμαστικά πριν μπω στον βρόχο, παρατηρώ πως πλέον ειναι διαθέσιμη η __next__ για το συγκεκριμένο αντικείμενο b. Πως προέκυψε η next? Μπορεί η iter(), μεσω καποιου μηχανισμού να "δημιουργήσει" αυτη την dunder method?
2) Η κλήση της __next__ στην συγκεκριμένη περίπτωση, συνεπάγεται και άμεση κλήση της __getitem__???
Πολλές απορίες.... :-)

mgkillme
Автор

Καλησπέρα Δάσκαλε
Μια μικρή απορία



class X:
def __init__(self):
self.__ar = [x for x in range(1, 6)]
self.k = [i for i in range(1, 9)]
self.x = 1
# [1, 2, 3, 4, 5]

def __getitem__(self, i): #obj[i] || dhladh self[i] || __getitem__(self, i) = [i] ( [] )
l = [self.k[i]]
return l


def __len__(self):
return len(self.k)



obj = X() # obj.ar [1, 2, 3, 4, 5]


for k in obj: # for i in range(len(obj)):
print(id(k), k) # k = obj[i] __getitem__(self, i) | line 6

Αγνοηστε προφανώς τα σχόλια.
Αν το τρέξετε θα τυπώσει το id του k και μετά το k (το k είναι πίνακας) για 8 φορές.
Γιατι το Id συμπεριφέρεται έτσι (κάνει εναλλαγές)

chrispan
Автор

Από το βίντεο καταλαβαίνω ότι οι μέθοδοι __len__ και __getitem__ πάνε πακέτο όταν θέλουμε να κάνουμε επανάληψη επί ενός αντικειμένου. Τρέχοντας όμως το παράδειγμα 3 (iterate.py), διαγράφοντας τη __len__ η επανάληψη γινόταν κανονικά(το έτρεξα για να δω τι σφάλμα θα βγάλει). Το pycharm έβγαζε ακριβώς το ίδιο αποτέλεσμα.
Στην άσκηση 9 όρισα τη __len__ για να κάνω επανάληψη και ύστερα από δοκιμές διαπίστωσα ότι χωρίς τη __len__ δε μπορεί να γίνει επανάληψη.
Παρατήρησα ότι η άσκηση 9 με το παράδειγμα 3 διαφέρουν στην __init__
Στο παράδειγμα 3 ορίζεται πίνακας ενώ στην άσκηση 9 ορίζονται ξεχωριστά οι μεταβλητές.
Αυτός είναι και ο λόγος που το παράδειγμα 3 τρέχει και χωρίς να υπάρχει η __len__ ;

petrosgkousioudis
Автор

Κυριε Ψουνη εγω πηγα να κανω την μεθοδο len με την εξης μεθοδο!
def __len__(self):
len_list = []
len_list.append(self.x)
len_list.append(self.y)
len_list.append(self.z)
return len(len_list)

Δουλευει οσον αφορα το μημος, ωστοσο οταν εφτιαξα και την getitem και πηγα να κανω επαναληψη επανω στο αντικειμενο για να δω ανα δουλευει, εβγαλε εναν ατερμον βροχο ο οποιος επεστρεφε συνεχως Νοne.
Παραθετω τον κωδικα μου παρακατω.

class Point3d:
def __init__(self, x=None, y=None, z=None) -> None:
if x == None:
self.x = 0
else:
self.x = x
if y == None:
self.y = 0
else:
self.y = y

if z == None:
self.z = 0
else:
self.z = z

def __str__(self) -> str:
return f'({self.x}, {self.y}, {self.z})'

#This creates a new object if we want to add two objects together
def __add__(self, other):
new_point = Point3d()
if isinstance(other, Point3d):
new_point.x = self.x + other.x
new_point.y = self.y + other.y
new_point.z = self.z + other.z
return new_point
elif isinstance(other, int):
new_point.x = self.x + other
new_point.y = self.y + other
new_point.z = self.z + other
return new_point

def __iadd__(self, other):
if isinstance(other, Point3d):
self.x += other.x
self.y += other.y
self.z += other.z
return self.x, self.y, self.z
elif isinstance(other, int):
self.x += other
self.y += other
self.z += other
return self.x, self.y, self.z
def __len__(self):
len_list = []
len_list.append(self.x)
len_list.append(self.y)
len_list.append(self.z)
return len(len_list)

def __getitem__(self, pos):
if pos == 0:
return self.x
elif pos == 1:
return self.y
elif pos == 2:
return self.z
else:
return None

def __setitem__(self, pos, value):
if pos == 0:
self.x = value
elif pos == 1:
self.y = value
elif pos == 2:
self.z = value
else:
return None
return self.x, self.y, self.z

konstantinostzaferis