NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Jakub Vokáč:29.11.2021 19:53

Ahoj, zkusim se tu zeptat na neco okolo deskriptoru z prikladu v kurzu OOP v pythonu:
https://www.itnetwork.cz/…-deskriptory

Kdyz pouziju deskriptor tridy Typed a tridu Person, ktera Typed pouziva:

from weakref import WeakKeyDictionary

class Typed:

    dictionary = WeakKeyDictionary()

    def __init__(self, ty=int):
        self.ty = ty

    def __get__(self, instance, owner=None):
        print("Getting instance")
        return self.dictionary[instance]

    def __set__(self, instance, value):
        print("Setting instance", instance, "to", value)
        if not isinstance(value, self.ty):
            raise TypeError("Value must be type {}".format(self.ty))
        self.dictionary[instance] = value


class Person:

    name = Typed(ty=str)
    age = Typed()
    weight = Typed(ty=float)

    def __init__(self, name, age, weight):
        self.name = name
        self.age = age
        self.weight = weight

k vytvoreni objektu s danymi hodnotami parametru:

tchyne = Person('Marfusa', 71, 123.4)
print(tchyne.name, tchyne.age, tchyne.weight)

ocekaval bych, ze se vypisou hodnoty vsech parametru, ale vypise se jen 3x ten posledni:

Setting instance <__main__.Person object at 0x7f1c608f05e0> to Marfusa
Setting instance <__main__.Person object at 0x7f1c608f05e0> to 71
Setting instance <__main__.Person object at 0x7f1c608f05e0> to 123.4
Getting instance
Getting instance
Getting instance
123.4 123.4 123.4

Vypada to, ze vsechny 3 vytvorene deskriptory odkazuji na stejny objekt.

Zkusil jsem: Kdyz necham vypsat ten tridni slovnik v Typed:

for i, j in list(Typed.dictionary.items()):
    print('{0} : {1}'.format(i, j))

vypise se jen jeden par klic->hodnota:

<__main__.Person object at 0x7f10d86035e0> : 123.4

Moje dalsi myslenka byla, ze hodnoty do tridniho slovniku <dictionary> se vkladaji pres tridu a tudiz bude mit kazda instance deskriptoru svuj vlastni. Neco jako:

slovnik pro instanci Typed 'name':
objekt Person 'tchyne' : 'Marfusa'
jiny objekt Person : 'jmeno jineho objektu'
jiny objekt1 Person : 'jmeno jineho objektu1'
jiny objekt2 Person : 'jmeno jineho objektu2'
...

Kdyz chci ale vypsat slovnik tridniho atributu 'name', nedostanu co bych ocekaval:

for i, j in list(Person.name.dictionary.items()):
    print('{0} : {1}'.format(i, j))

# vypise : TypeError: cannot create weak reference to 'NoneType' object

Kdyz jsem koukal na tridy deskriptoru popsane jinde, byly stavene jinak, coz ale nic neznamena.

Jeste jsem zkousel vypsat slovnik s atributy __dict__ objektu tchyne, ale ten je prazdny:

print(tchyne.__dict__) #vypise: {}

Chci docílit: Objekt tridy Person by mel mit pristupne 3 ruzne atributy.
Nasel by se nekdo, kdo by mi rek kde delam chybu v pouziti teto konkretni tridy deskriptoru?
Dik.

 
Odpovědět
29.11.2021 19:53
Avatar
Pavel
Člen
Avatar
Pavel:30.11.2021 12:53

Je to tím, že dictionary máte jako atribut třídy a ne instance, tj. je společný pro všechny instance. Vy si ho na konci přepíšete tou poslední hodnotou.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
30.11.2021 12:53
Avatar
Odpovídá na Pavel
Jakub Vokáč:30.11.2021 19:39

Diky za postreh, je to tak.
Tohle uz funguje:

class Typed:

    def __init__(self, ty=int):
        self.ty = ty
        self.dictionary = WeakKeyDictionary()

    def __get__(self, instance, owner=None):
        print("Getting instance")
        return self.dictionary[instance]

    def __set__(self, instance, value):
        print("Setting instance", instance, "to", value)
        if not isinstance(value, self.ty):
            raise TypeError("Value must be type {}".format(self.ty))
        self.dictionary[instance] = value
 
Nahoru Odpovědět
30.11.2021 19:39
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.