• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Nieoczekiwana rekursja w Pythonie

VPS Starter Arubacloud
0 głosów
401 wizyt
pytanie zadane 14 czerwca 2021 w Python przez mattaha Użytkownik (690 p.)

Witam. Mam problem z klasą setwrapper.SetSub. Klasa SetSub ma rozszerzać klasę Set i ma symulować dzialanie listy za pomocą zbioru. Gdy importuję w sesji interaktywnej moduł po czym próbuję wywołać konstruktor wywala mi coś takiego:

>>> from setwrapper import SetSub
>>> SetSub(1, 2, 3)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/home/z3us/PycharmProjects/python_wprowadzenie/setwrapper.py", line 46, in __init__
    super(SetSub, self).__init__(value)
  File "/home/z3us/PycharmProjects/python_wprowadzenie/setwrapper.py", line 3, in __init__
    self.data = []
  File "/home/z3us/PycharmProjects/python_wprowadzenie/setwrapper.py", line 58, in __setattr__
    if value not in self.data:
  File "/home/z3us/PycharmProjects/python_wprowadzenie/setwrapper.py", line 52, in __getattr__
    if item in self.data:
  File "/home/z3us/PycharmProjects/python_wprowadzenie/setwrapper.py", line 52, in __getattr__
    if item in self.data:
  File "/home/z3us/PycharmProjects/python_wprowadzenie/setwrapper.py", line 52, in __getattr__
    if item in self.data:
  [Previous line repeated 983 more times]
RecursionError: maximum recursion depth exceeded

Kod:

class Set:
    def __init__(self, value=[]):
        self.data = []
        self.concat(value)

    def intersect(self, other):
        res = []
        for x in self.data:
            if x in other:
                res.append(x)
        return Set(res)

    def union(self, other):
        res = self.data[:]
        for x in other:
            if not x in res:
                res.append(x)
        return Set(res)

    def concat(self, value):
        for x in value:
            if not x in self.data:
                self.data.append(x)

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

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

    def __and__(self, other):
        return self.intersect(other)

    def __or__(self, other):
        return self.union(other)

    def __repr__(self):
        return 'Zbiór: ' + repr(self.data)

    def __iter__(self):
        return iter(self.data)


class SetSub(Set):
    def __init__(self, *value):
        super(SetSub, self).__init__(value)

    def __add__(self, other):
        return self | other

    def __getattr__(self, item):
        if item in self.data:
            return self.data[item]
        else:
            raise IndexError()

    def __setattr__(self, key, value):
        if value not in self.data:
            self.data[key] = value

    def append(self, item):
        if item not in self.data:
            self.data.append(item)

 

1 odpowiedź

+1 głos
odpowiedź 14 czerwca 2021 przez adrian17 Ekspert (344,100 p.)
wybrane 14 czerwca 2021 przez mattaha
 
Najlepsza

i ma symulować dzialanie listy za pomocą zbioru

Symulować zbiór za pomocą listy? :)

Nie do końca rozumiem czym się różni Set od SetSub, nazwy mało mówią :(

Ale na pewno chodzi Ci o __getattr__, a nie o __getitem__? Bo getattr, setattr pośredniczą przy każdej operacji typu `self.costam`, więc nic dziwnego że masz rekursję.

komentarz 14 czerwca 2021 przez mattaha Użytkownik (690 p.)
Dzięki pomogłeś! Faktycznie pomyliłem metody

Podobne pytania

+1 głos
3 odpowiedzi 494 wizyt
pytanie zadane 29 października 2021 w Python przez defałlt juzer Obywatel (1,140 p.)
0 głosów
3 odpowiedzi 470 wizyt
0 głosów
1 odpowiedź 406 wizyt
pytanie zadane 25 listopada 2021 w Python przez doskanoness Obywatel (1,240 p.)

92,452 zapytań

141,262 odpowiedzi

319,085 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...