Jak zpřístupnit vlastnost nadřazené třídy? – Python – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak zpřístupnit vlastnost nadřazené třídy? – Python – Fórum – Programujte.comJak zpřístupnit vlastnost nadřazené třídy? – Python – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
oxidián0
Grafoman
26. 9. 2024   #1
-
0
-

Mám jednu rodičovskou třídu a uvnitř konstruktoru dávám vytvořit novou instanci další třídy:

self.transpose ...

poté parsuju txt soubor a ukládám data break (ř. 108) :

self.transpose.add_form_to_conjugation(self.current_table_name, self.current_column_name, kmen, koncovka, preceding_string)

uvnitř metody pak chci dát:

    def add_form_to_conjugation(self, conjugation, time, kmen, koncovka, preceding_string=None):
        # Uložíme formu jen pokud je daný čas relevantní pro konjugaci
        print(self.current_table_name)


conjugation
 a
current_table_name
 nadřazené třídy tedy self.transpose.current_table_name má mít stejnou hodnotu.

Takže se snažím zjistit jak se mohu dostat k tomu uloženému elementu, aniž bych volal __init__ nadřazené třídy nebo přes to super. mi to nešlo.

PS:

Já zkoušel GPT ale nikam to nevede, to má tendenci furt vkládat volání iniciaci konstruktoru nadřazené třídy super.__init__ ... ale to by vedlo k zacyklení nebo nějakým problémům volat zevnitř konstruktoru zase zpět sebe sama je nesmysl.

Nahlásit jako SPAM
IP: 94.113.182.–
Jerry
~ Anonymní uživatel
512 příspěvků
26. 9. 2024   #2
-
0
-

https://www.tutorialspoint.com/how-to-access-a-parent-class-attribute-in-python

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:a5f2:3d6f:b690:ff01...–
gna
~ Anonymní uživatel
1891 příspěvků
26. 9. 2024   #3
-
0
-

Když inicializuješ instanci odvozené třídy, tak většinou pochopitelně chceš i inicializaci definovanou v té rodičovské třídě. Obzvlášť pokud se tím dynamicky vytvářejí vlastnosti, což se v Pythonu běžně dělá. Pokud se to nějak zacyklí, tak je to prostě blbě napsané.

class A:
    def __init__(self):
        self.x = 1

class B(A):
    def __init__(self):
        super().__init__() # A.__init__
        self.y = 2

    def z(self):
        print(f"{self.x=}, {self.y=}")

a = A()
print(f"{a.x=}")
b = B()
print(f"{b.x=}, {b.y=}")
b.z()
Nahlásit jako SPAM
IP: 213.211.51.–
gna
~ Anonymní uživatel
1891 příspěvků
26. 9. 2024   #4
-
0
-

Neviděl jsem Jerryho odpověď a napsal jsem prakticky to samé, co je na tom jeho odkazu :)

Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
26. 9. 2024   #5
-
0
-

#3 gna
Když to super.__init__(sloveso, hledane_kmeny) tam přidám:

    
class VerbParser:
    def __init__(self, sloveso, hledane_kmeny):
 
        self.transpose = VerbParserTranspose(sloveso, hledane_kmeny) 

class VerbParserTranspose(VerbParser):
    def __init__(self, sloveso, hledane_kmeny):
        super.__init__(sloveso, hledane_kmeny)

dostávám chybu:

    super.__init__(sloveso, hledane_kmeny)
TypeError: descriptor '__init__' requires a 'super' object but received a 'str'

Nahlásit jako SPAM
IP: 94.113.182.–
oxidián0
Grafoman
26. 9. 2024   #6
-
0
-

Já měl původně parsovací funkci, která čte tabulku (txt data) po řádcích, tj. parsovač.

Pak jsem to chtěl rozšířit aby data z tabulek byla transponované a sbírané po sloupcích, což dává větší smysl.

Proto jsem chtěl pod ten VerbParser dát child a přistupovat k tomu tak: self.transpose.metoda()

Ještě jsem zkoušel zeptat se GPT jestli je ten design špatný, tvrdí že jo. Ale nechce mi vytvořit to co chci, on nakonec prohodil wrappovací třídu a udělal z toho child. Takže jsem z toho úplně mimo a nevyznám se v tom jak to mám řešit.

https://chatgpt.com/share/66f59886-9d78-8007-ac67-73845813d8c6

Nahlásit jako SPAM
IP: 94.113.182.–
gna
~ Anonymní uživatel
1891 příspěvků
26. 9. 2024   #7
-
0
-

Dědičnost je o tom, že můžeš vytvořit třídu odvozenou z jiné třidy a ta nová třída je "potomek", který automaticky dědí všechno od "rodiče" a může něco přidat nebo změnit. A když nějakou metodu nahradíš a chceš volat tu původní, tak se k ní dostaneš přes super. (A super je funkce, takže ti tam pro její volání chybí závorky.)

Ale toto nevypadá, že bys základní "VerbParser" chtěl trochu upravit na "VerbParserTranspose", který navíc dělá transpose.

Pokud je to nezávislá pomocná třída, tak tam dědičnost vůbec neřeš. A problém je teď jen v tom (aspoň, co vidím), že ve "VerbParserTranspose.__init__" voláš rodičovský __init__, který neexistuje (resp. automaticky dědíš obecný "object.__init__", který neví, co s těmi parametry).

Ale ty to teda asi chceš provázat ještě nějak jinak. Jak? :)

Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
27. 9. 2024   #8
-
0
-

#7 gna
Třída VerbParserTranspose je závislá na rodič. třídě.

Protože v rod. třídě je tato metoda, která volá

def add_form_to_kmen(self, sword):

...

     self.transpose.add_data_to_conjugation(self.current_table_name, self.current_column_name, kmen, koncovka, self.adverbs[self.adverb_counter-1], self.adverb_counter, preceding_string)


To znamená, zatímco Parser parsuje data, ukládá slovíčka i do "kontejneru" transpose... Říkám tomu tedy kontejner... Ale v podstatě je to třída, která obsahuje tyto prostředky na strukturální ukládání dat, tak aby bylo možné k nim snadno přistoupit a vypsat data po sloupcích. Takže během parsování transpose slouží k převodu řádků na sloupce. To je ta závislost.

Rodičovský __init__ existuje, musí existovat:

class VerbParser:
    def __init__(self, sloveso, hledane_kmeny):
        self.sloveso = sloveso
        self.hledane_kmeny = hledane_kmeny
        self.new_table = False
        self.table_counter = 0
        self.tr_counter = 0
        self.current_table_raw_no = 0
        self.header_column_counter = 0
        self.column_counter = 0
        self.adverb_counter = -1
        self.current_adverb = ""
        self.person = None
        self.last_line_adverb = ""
        self.process_next_word_in_cell = False
        self.verb_forms = {kmen: [] for kmen in hledane_kmeny}
        self.verb_forms_precedes = {kmen: [] for kmen in hledane_kmeny} # Toto je kontejner na slovíčka, která nejsou součástí kmene zpracovávaného slovesa, nutno sbírat i prázdné výskyty.
        self.verb_forms_check = {kmen: 0 for kmen in hledane_kmeny} # data o tom kolik je tam záznamů - !!! Také slovo bez koncovky se počítá do verb_forms_check jako jeden z tvarů
        self.verb_no_form = {kmen: False for kmen in hledane_kmeny} # data o tom zda se daný kmen nachází na řádku v identické podobě bez koncovky
        self.verb_forms_dupl_ignored = 0
        self.table_names = []
        self.column_names = []
        self.adverbs = []
        self.current_table_name = None
        self.current_column_name = None
        self.is_last_tr_detected = False
        self.is_last_column_detected = False
        self.is_last_cell = False
        self.i = 0

        # VerbParserTranspose - Rozšiřující třída: Přidání kontejneru pro transpozici - čas, osoba, koncovka
        self.transpose = VerbParserTranspose(sloveso, hledane_kmeny)

Tak proto jsem myslel, že by tam mělo být toto

class VerbParserTranspose(VerbParser):
    def __init__(self, sloveso, hledane_kmeny):
        super().__init__(sloveso, hledane_kmeny)

ovšem neumím realizovat to aby třída byla strukturovaná na více úrovních - přehledná, že se nevolají všechny metody ze stejného místa, z jednoho wrapujícího objektu, ale že se volají z transpose, aby bylo jasné, k čemu data a metody jsou. Tím se odděluje Parser jako takový od dat určených k výpisu. I když Parser taky shromažďuje data, ale jen kmeny a koncovky jako vše... Tam není žádné filtrování.

V případě že by nebylo možné v pythonu dosáhnout takové struktury jako já znám třeba z JQuery (JS) (i když srovnání s asynchronním jazykem možná není přesné)... Tak bych musel mít dvě oddělené třídy, zavést instanci transpose... a pak zavést instanci toho parseru - do jehož konstruktoru bych předal instanci transpose...

Nahlásit jako SPAM
IP: 94.113.182.–
gna
~ Anonymní uživatel
1891 příspěvků
27. 9. 2024   #9
-
0
-

Já tomu vůbec nerozumím. Buď chceš tu dědičnost 

class VerbParser:
    ...
class VerbParserTranspose(VerbParser):
    ...

A pak VerbParser nebude vytvářet instanci VerbParserTranspose. Místo VerbParser prostě použiješ VerbParserTranspose, který má všechno z VerbParser a něco navíc a/nebo jinak.

Nebo je VerbParserTranspose pomocná nezávislá třída a vztah rodič-potomek tam není. 

class VerbParser:
    ...
class VerbParserTranspose:
    ...

A pak VerbParserTranspose na volání vlastních metod nepotřebuje `self.transpose` z "rodiče", ale jen `self`. A kdyby náhodou potřebovala přistupovat k tomu "rodiči" tak je to zase jen proměnná, kterou jí musíš zase předat.

Dělal jsi přece v Delphi, ten objektový model je praktický stejný.

Nahlásit jako SPAM
IP: 213.211.51.–
oxidián0
Grafoman
27. 9. 2024   #10
-
0
-

#9 gna
Delphi si teď moc nepamatuji je to už dost let. Od dubna 2023 se učím v Linuxu, Bash, Python. Na freepascal jsem neměl čas.

Nahlásit jako SPAM
IP: 94.113.182.–
oxidián0
Grafoman
27. 9. 2024   #11
-
0
-

Vymyslel jsem to takto:

class VerbParser:
def __init__(self, sloveso, hledane_kmeny):def add_form_to_kmen(self, sword):
    self.transpose.add_data_to_conjugation(self.current_table_name, self.current_column_name, kmen, koncovka, self.adverbs[self.adverb_counter-1], self.adverb_counter, preceding_string)def parse_line(self, line):
self.transpose = Transpose(self)

class Transpose():
def __init__(self, Parser):
def add_data_to_conjugation(self, conjugation, time, kmen, koncovka, adverb, person, preceding_string=None):def print_conjugation(self, conjugation, with_preceding=False):




Chybu to zatím nehází, zatím ale nevidím, že bych měl v tom kontejneru nějaký data.

Budu řešit později.

Nahlásit jako SPAM
IP: 94.113.182.–
Zjistit počet nových příspěvků

Přidej příspěvek

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 3 hosté

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý