class variable

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
de_dieter
User
Beiträge: 3
Registriert: Dienstag 24. Januar 2017, 14:38

hi

ich versteh ein teil eines Programms icht

ich habe folgenden code

Code: Alles auswählen

class test(object):
    __pro={}
    
    @classmethod
    def cal(cls,k):
       dev=cls.__pro
        for des in k:
        dev[des] = {}
        dev=dev[des]
       print ("cls", cls.__pro)
       print (dev)
test.cal(k)       
      
bekomme ich folgende Ausgabe.

cls {1: {}}
{}
cls {1: {2: {}}}
{}
cls {1: {2: {3: {}}}}
{}
cls {1: {2: {3: {4: {}}}}}
{}
cls {1: {2: {3: {4: {5: {}}}}}}
{}

wieso wird das in die class variable cls.__pro geschrieben?
ich weiße ja nichts mehr der Variable zu in form von

cls.__pro=dev[des]

kann mir jmd erklären wieso das in die Variable geschrieben wird?
Zuletzt geändert von Anonymous am Dienstag 24. Januar 2017, 14:52, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@de_dieter: Du bindest tatsächlich nichts an das Attribut aber Du veränderst das Wörterbuch. Du bindest es an den lokalen Namen `dev` und veränderst es in der Schleife dann.

Allerdings solltest Du da sowieso keine veränderlichen Attribute auf der Klasse haben, denn das ist letztendlich globaler Zustand der mehr Probleme macht als löst. Und die doppelten führenden Unterstriche sind falsch. Das sollte wenn überhaupt nur einer sein.
de_dieter
User
Beiträge: 3
Registriert: Dienstag 24. Januar 2017, 14:38

was ich immernoch net versteh ist das ich ja

dev={} setzte wieso wird dann nicht __pro= {} gesetzt sondern behält den Eintrag __pro={1:{}} für die erste iteration??
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@de_dieter: ich versteh den Code auch nicht, weil alle Namen nur kryptische 3 Buchstaben sind. Variablennamen sollten aussagekräftig sein. Die Einrückung stimmt nicht und sollte auch immer 4 Leerzeichen pro Ebene sein, nicht mal zwei und mal nur eines. Was ist denn mit cal gemeint? Du setzt nirgends dev={}, sondern nur ein Element von dev (dev[des]) auf {}.
BlackJack

@de_dieter: Wo setzt Du ``dev={}``? Nicht in dem gezeigten Quelltext.
de_dieter
User
Beiträge: 3
Registriert: Dienstag 24. Januar 2017, 14:38

ist denn nicht
dev[des]={}
dev=dev[des] ==> dev={}

sry fang erst an python zu lernen. hab eher Java programmiert
BlackJack

@de_dieter: Nein ist es nicht. ``a_dict[key] = value`` ist ``aMap.put(key, value);`` in Java.
BlackJack

Das Beispiel mal in Java mit einer statischen Methode statt einer Klassenmethode (das macht hier keinen Unterschied):
[codebox=java5 file=Unbenannt.java]import java.util.HashMap;
import java.util.Map;

public class Test {
static private Map pro = new HashMap();

public static void cal(int[] k) {
Map dev = Test.pro;
for (int des : k) {
dev.put(des, new HashMap());
dev = (Map) dev.get(des);
System.out.println(pro);
System.out.println(dev);
}
}

public static void main(String[] args) {
cal(new int[]{1, 2, 3, 4, 5});
}
}[/code]
Ausgabe sieht entsprechend wie bei Python aus:
[codebox=text file=Unbenannt.txt]{1={}}
{}
{1={2={}}}
{}
{1={2={3={}}}}
{}
{1={2={3={4={}}}}}
{}
{1={2={3={4={5={}}}}}}
{}[/code]
Benutzeravatar
pyHoax
User
Beiträge: 84
Registriert: Donnerstag 15. Dezember 2016, 19:17

Allerdings solltest Du da sowieso keine veränderlichen Attribute auf der Klasse haben, denn das ist letztendlich globaler Zustand der mehr Probleme macht als löst.
Ich verwende manchmal eine Classenvariable wenn ich den Objekten der Klasse eine laufende ID geben will.

Code: Alles auswählen

from itertools import count
class Genom():
    __last_id=count(0)

    def __init__(self,):
        self._id = next(Genom.__last_id)

    def __str__(self):
        return "Genom #%i:" % self._id
Allerdings vermute ich das für genau diesen Fall in Python die Batterien bereits eingebaut sind .. wenn ja, wo sind Sie ?
Kann ich mir diese ID Generierung vereinfachen ? (Ok.. ist bereits ziemlich platt)

Ich brauche hier wirklich einen eigenen Identifier für jedes Objekt weil in der genetischen Simulation Verwandtschaftstest gemacht werden.
Ich kann leider keine Referenzen verwenden, da die Verwandtschaft auch über bereits 'tote' Verwandte berechnet werden soll... wäre ungünstig für den GC.
BlackJack

@pyHoax: Das wäre eine Ausnahme von der Regel. Wobei da ein Unterstrich zu viel ist. Und statt ``Genom.__last_id`` würde ich ``self.__last_id`` schreiben.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@pyHoax: für was brauchst Du eine ID? Meistens ist die Antwort darauf, dass man eigentlich gar keine ID braucht, sondern etwas anderes will, oder dass bei der Erzeugung eines Objekts gar nicht die richtige ID erzeugt werden kann, sondern dass man die ID außerhalb erzeugen muß.

Für was brauchst Du eine ID?
Benutzeravatar
pyHoax
User
Beiträge: 84
Registriert: Donnerstag 15. Dezember 2016, 19:17

Für was brauchst Du eine ID?
Es ist die Genom Klasse in einer Simulation für genetische Algorithmen.
Um Inzucht beim Crossover (Sexuelle Reproduktion) zu verhindern wird erst geprüft ob die gewählten Eltern nicht Geschwister sind oder gar eine Eltern-Kind Beziehung haben.

Wenn ich anstelle einer ID z.B die Referenz auf die Eltern speichern würde.. kann der GC verstorbene Vorfahren (aussortierte Lösungen) nicht abräumen, der Speicher würde sich sprichwörtlich mit den Genomen von Adam und Eva an füllen. (Nix Zyklisch .. du hast einen ordentlichen Familienstammbaum)

Die Sequenz von count ist absolut ausreichend, sie wird nur innerhalb der Simulation benötigt. Es ist sozusagen der Eindeutige Vornahme des Individuums mit dem Genom.
Der Familienname setzt sich dann aus den Vornamen der Eltern zusammen.

Sprich: Genom #5, Kind von Genom #2 und Genom #4 (Wir sind die Borg...)

Mehr brauch ich nicht.
l. Wobei da ein Unterstrich zu viel ist. Und statt ``Genom.__last_id`` würde ich ``self.__last_id`` schreiben.
Ist die explizite Nennung der Klasse nicht die offensichtlichere Wahl ?
BlackJack

@pyHoax: Ich find's halt flexibler wenn man davon Klassen ableiten kann und denen die Möglichkeit von eigenen IDs geben kann.
Antworten