zugriff auf class-variable aus superklasse

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

Dienstag 27. Februar 2007, 17:19

tja, wie macht man das?
(siehe exception unten)

danke schonmal :)

Code: Alles auswählen


class Multiton( object ):
    __instances = {}
    def __new__( cls, key ):
        if not key in cls.__instances:
            cls.__instances[key] = object.__new__(cls, key)
        return cls.__instances[key]
    def __init__(self, key):
        self.key = key
    
    @classmethod
    def debug_instances(cls):
        for k, v in cls.__instances.items():
            print v
    



class MultitonErbe( Multiton ):
    
    #(...)
    
    @classmethod
    def sth_useful(cls):
        for k, v in cls.__instances.items():
            print v

>>> Multiton.debug_instances()
funktioniert!
>>> MultitonErbe.debug_instances()
funktioniert!
>>> MultitonErbe.sth_useful()
(...)
AttributeError: type object 'MultitonErbe' has no attribute '_MultitonErbe__instances'
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 27. Februar 2007, 17:24

Die einfachste Lösung: auf Name-Mangling verzichten und aus den ``__instances`` einfach ``_instances`` oder gar nur ``instances`` zu machen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dienstag 27. Februar 2007, 17:25

Code: Alles auswählen

class MultitonErbe( Multiton ): 
    
    #(...) 
    
    @classmethod 
    def sth_useful(): 
        for k, v in Multiton .__instances.items(): 
            print v 
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

Dienstag 27. Februar 2007, 17:31

instances sollte schon private sein.

EyDu, mit deiner lösung arbeitet sth_useful() auf den instanzen aller klassen die von multiton erben, das darf nicht.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 27. Februar 2007, 19:49

Dill hat geschrieben:instances sollte schon private sein.
Private gibt es in Python nicht, so ein Mechanismus ist nicht eingebaut. Es gibt nur Name-Mangling oder gar nichts.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

Dienstag 27. Februar 2007, 20:08

Der Sinn des name mangling bei klassenvariablen ist der schutz der variable.
Und das möchte ich tun.

Wenn du es so genau nimmst, gibt es in Java auch keine privaten variablen (afaik kann man über reflection an die privaten variablen kommen) und in C++ geht das mit sicherheit auch ... wie auch immer ...
BlackJack

Dienstag 27. Februar 2007, 22:05

Der Sinn des "name mangeling" ist *nicht* Zugriffsschutz, sondern dass der Name in Subklassen wiederverwendet werden kann, ohne das Kollisionen entstehen. Genau das willst Du ja offensichtlich nicht, also nimm keine zwei Unterstriche.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

Mittwoch 28. Februar 2007, 01:14

hmm gut zu wissen ... da hab ich wohl was falsch verstanden :oops:

...naja also kein wunder, dass das nicht geht :)
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

Mittwoch 28. Februar 2007, 23:01

Hi,


habe jetzt also den doppelten underscore in einen einfachen geändert.
Jetzt gibt aber MultitonErbe.sth_useful() auch die instanzen von
Dummy(Multiton) aus.
Was mache ich falsch?

(ich möchte nicht explizit in sth_useful() testen ob _instances.item() instanz von MutlitonErbe ist.)

Code: Alles auswählen


class Multiton( object ):
    _instances = {}
    def __new__( cls, key ):
        if not key in cls._instances:
            cls.__instances[key] = object.__new__(cls, key)
        return cls._instances[key]
    def __init__(self, key):
        self.key = key
   
    @classmethod
    def debug_instances(cls):
        for k, v in cls._instances.items():
            print v
   

class Dummy( Multiton ):
    pass


class MultitonErbe( Multiton ):
   
    #(...)
   
    @classmethod
    def sth_useful(cls):
        for k, v in cls._instances.items():
            print v 
BlackJack

Donnerstag 1. März 2007, 10:12

Da schlägt die ganz normale Vererbung zu, die Unterklassen erben `_instances` von `Multiton`. Du kannst das Attribut einfach bei Bedarf erzeugen:

Code: Alles auswählen

class Multiton( object ): 
    # _instances = {} 
    def __new__(cls, key):
        if not hasattr(cls, '_instances'):
            cls._instances = dict()
        if key not in cls._instances:
            cls._instances[key] = object.__new__(cls, key)
        return cls._instances[key]
Antworten