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

OOP w Pythonie, klasa nie daje takich samych wyników jak przy zastosowaniu funkcji

Object Storage Arubacloud
+1 głos
267 wizyt
pytanie zadane 25 lipca 2022 w Python przez gblaze Nowicjusz (240 p.)

Ostatnio w Pythonie probowalem rozwiazac pewne zadanie, które polegało na tym, aby uzyć domyślnej biblioteki "random" i jej metody "choice", aby wygenerować 4 znakowy ciąg znaków z listy [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 'a', 'b', 'c', 'd', 'e']. Jeden taki ciąg miał być ciągiem którego wylosowanie gwarantuje wygranie nagrody, a drugi (użytkownika) jesli jest taki sam, prowadzi do wygranej.

Używając funkcji, program sprawdza ten warunek poprawnie:

from random import choice
import time
 
def prize():
    random_characters = [1,2,3,4,5,6,7,8,9,0,'a','b','c','d','e']
    selected_characters = []
 
    for i in range(0,4):
        character = choice(random_characters)
        selected_characters.append(character)
        random_characters.remove(character)
 
    message = ""
 
    for character in selected_characters:
        message += str(character)
 
    return message
 
active = True
 
while active:
    message = prize()
    winning_message = prize()
    if message == winning_message:
        active = False
 
    print(f"Any ticket matching these four characters: {message} will win the prize!")
    print(f"My ticket: {winning_message}")
    time.sleep(1)

Rezultat:

Natomiast kiedy chciałem zastosowac podejście obiektowe i zainicjować funkcje, ciag znakow dodaje sam do siebie poprzedni ciag znaków z poprzedniej iteracji pętli. Czy ktoś byłby mi w stanie wytlumaczyć dlaczego?

Kod:

from random import choice
import time
 
class Prize():
    def __init__(self):
        self.random_characters = [1,2,3,4,5,6,7,8,9,0,'a','b','c','d','e']
        self.selected_characters = []
        self.message = ""
 
    def randomize(self):
        for i in range(0,4):
            character = choice(self.random_characters)
            self.selected_characters.append(character)
            self.random_characters.remove(character)
 
        for i in self.selected_characters:
            self.message += str(i)
 
        return self.message
 
active = True
message = Prize() 
winning_message = Prize()
 
while active:
    random_ticket = message.randomize()
    my_ticket = winning_message.randomize()
    if random_ticket == my_ticket:
        active = False
 
    print(f"Any ticket matching these four characters: {random_ticket} will win the prize!")
    print(f"My ticket: {my_ticket}")
    time.sleep(1)

Wynik:

Z góry dziękuję za odpowiedź!

1 odpowiedź

+3 głosów
odpowiedź 25 lipca 2022 przez Nelson89 Dyskutant (7,720 p.)
edycja 25 lipca 2022 przez Nelson89

Cześć,

dzieje się tak dlatego, że przy pierwszej metodzie, w ciele funkcji zostaje utworzona lista na wylosowane znaki. Za każdym razem, gdy wywołujesz tą funkcje lista jest tworzona od nowa.

W drugim przypadku, gdy tworzysz obiekt, tworzona jest lista na wylosowane obiekty. Ta lista jest tworzona tylko i wyłącznie, gdy tworzysz obiekt tej klasy - za każdym razem, gdy wywołujesz funkcje randomize, to do listy są dodane nowe obiekty. Listę stworzono w konstrukorze __init__, która jest wywoływana przy tworzeniu obiektu.

Aby tego uniknąć, to do każdego losowania tworzysz nowy obiekt, albo (co bardziej sensowne) listę tworzysz w ciele funkcji (podobnie jak w pierwszym przypadku) - jako zmienną lokalną, a nie atrybut klasy (czyli bez self).

Jeszcze mała podpowiedź jak połączyć elementy listy w ciąg znaków, gdy wszystkie elementy będą obiektami klasy str.

"".join(['a', 'b', 'c'])

w cudzysłowie powinien się znajdować znak, który ma oddzielać elementy z listy.

Pozdrawiam,

Nelson

1
komentarz 25 lipca 2022 przez gblaze Nowicjusz (240 p.)
Wow, super, dzięki wielkie za pomoc!

Podobne pytania

0 głosów
1 odpowiedź 182 wizyt
pytanie zadane 18 lipca 2019 w Python przez RafalS VIP (122,820 p.)
+2 głosów
1 odpowiedź 608 wizyt
pytanie zadane 22 maja 2017 w PHP przez ŁukaszD. Użytkownik (540 p.)
0 głosów
3 odpowiedzi 316 wizyt

92,572 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,959 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...