Seite 1 von 1

in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Sonntag 30. Mai 2010, 14:50
von LiLaLaunebär
hi, habe folgenden code, der folgendes tut:

es wird ein neues Product erzeugt, dann wird der benötigte Input gesammelt (ebenfalls Products) und diese werden dann an das neue Product angehängt. Allerdings akkumulieren sich die Inputs.
Also wenn ich z.b. im 2. Schleifendurchgang NewProduct erzeuge, dann sind die Inputs aus dem vorherigen Schleifendurchlauf schon in der Product-eigenen List NewProducts.ComponentsAr...das sollte doch dann eig wieder leer sein...zumindes hat es per default den Wert [].
Warum wird die Referenz hier nicht gelöscht?

Code: Alles auswählen

for i in range(self.batchSize):
            NewProduct=Product(self.product)
            print NewProduct.ComponentsAr 
            for input,amount in self.InputAr:
                                 
                def getAmount(buff):
                    result=[]
                    counter=0
                    for x in buff:
                        if counter < amount and x.name == input:
                            result.append(x)
                            counter += 1
                        if counter >= amount:
                            break                        
                    return result
# yield belegt die list namens self.got mit Werten (Product Instanzen), die aus self.Preparationation        
# entnommen werden                       
                yield get,self,self.Preparation,getAmount 
                print "got %s" %self.got # liefert
                NewProduct.ComponentsAr.extend(self.got) # hier werden die Input Products angehängt
                            
            print "%s: creation %s" %(now(),NewProduct.ComponentsAr)

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Sonntag 30. Mai 2010, 15:06
von cofi
LiLaLaunebär hat geschrieben:das sollte doch dann eig wieder leer sein...zumindes hat es per default den Wert [].
Warum wird die Referenz hier nicht gelöscht?
Ich habe das Gefuehl, dass hier Code fehlt. Aber eigtl will ich nicht noch mehr davon sehn und empfehle dir mal PEP 8 zu lesen, denn deine Namen transportieren Null Information.

Zu dem Default Wert: Kann es sein, dass das in einer Funktion so definiert ist:

Code: Alles auswählen

 def foo(value=[]):
    ...
Wenn ja, ist hier dein Fehler, denn `value` wird nur einmal gebunden und hat ansonsten immer diesselbe Liste.

Und warum definierst du eigtl eine Funktion in einer 2-fachen Schleife?

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Sonntag 30. Mai 2010, 15:18
von LiLaLaunebär
danke für die Antwort.

ja, ich habe die funktion

Code: Alles auswählen

def foo (value=[]):
definiert, weil ich möchte, dass das Feld leer ist, wenn nichts übergeben wird.

wie löst man das elegant? value = None und dann if else in __init__?

Ansonsten fehlt Code, aber der ist nicht von Bedeutung für das Problem, würde aber die Variablennamen erklären. Bei der lokalen Funktion handelt es sich um ein Konstrukt, dass ich in der yield Funktion benutze.
Es muss eine lokale Funktion sein, da diese Filterfunktion genau ein Argument enthalten muss...das liegt am verwendeten Package...ist nur ein Entwurf, um zu sehen ob es überhaupt funktioniert, da ich einige Einschränkungen, die es durch das Package gibt, umgehen muss...
sehe gerade: Funktioniert aber auch, wenn die Funktion außerhalb der Schleife steht...dachte, das haut nicht hin, weil die lokalen Variablen noch nicht erzeugt sind...

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Sonntag 30. Mai 2010, 17:45
von Snoda
Am besten so:

Code: Alles auswählen

def foo(value=None):
    if value is None:
        value=[]

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Sonntag 30. Mai 2010, 18:38
von cofi
Snoda hat geschrieben:Am besten so:
Lieber:

Code: Alles auswählen

def foo(value=None):
    value = list() if value is None else value
Noch lieber:

Code: Alles auswählen

def foo(value=None):
    value = value if value else list() 
@LiLaLaunebaer: Ja, weil Python dynamisch Namen aufloest geht das, allerdings sollte man das sehr gut dokumentieren, dass es eine gewisse Umgebung braucht, oder noch besser uebergibt man das der Funktion.
Um das nochmal zu wiederholen: Du hast verstanden, warum deine Definition nicht funktioniert hat?

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Sonntag 30. Mai 2010, 21:21
von derdon
cofi:

Code: Alles auswählen

def foo(value=None):
    value = value or list()
funktioniert auch.

Edit: Nachteil ist natürlich, dass aus 0, False, '', set() etc. eine leere Liste wird. Wobei dieser Effekt vielleicht auch gewünscht sein kann, man sollte sich in jedem Fall dessen bewusst sein.

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Sonntag 30. Mai 2010, 22:55
von cofi
Ist mir bewusst, aber ich ziehe die explizite Form der Perligen vor. Meine 2. Variante hat den "Nachteil" auch, nur damit das nicht untergeht.

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Montag 31. Mai 2010, 10:32
von Darii
cofi hat geschrieben:
Snoda hat geschrieben:Am besten so:
Lieber:

Code: Alles auswählen

def foo(value=None):
    value = list() if value is None else value
Warum? Weil weniger lesbar? Weil langsamer?
Noch lieber:

Code: Alles auswählen

def foo(value=None):
    value = value if value else list() 
Lieber nicht, dann kann man der Funktion nämlich keine leeren Listen mehr übergeben.

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Montag 31. Mai 2010, 10:34
von DasIch
Darii hat geschrieben:Lieber nicht, dann kann man der Funktion nämlich keine leeren Listen mehr übergeben.
Solange die Funktion die Liste nicht verändert bleibt das Verhalten doch identisch.

Re: in Schleife Objekte erzeugen - Referenz bleibt?

Verfasst: Montag 31. Mai 2010, 10:47
von BlackJack
@DasIch: Mann kann dann aber zum Beispiel keine "eigene" leere Liste mehr übergeben ohne dass die durch eine normale Liste ausgetauscht wird. Und selbst bei Übergabe einer regulären leeren Liste wird unnötigerweise eine neue leere Liste erstellt.

Also ich finde die "altmodische" ``if``-Anweisung hier am besten. Ein ``if``-Ausdruck sieht mir zu sehr nach dem Versuch aus eine Zeile sparen zu wollen und besonders clever sein zu wollen.