in Schleife Objekte erzeugen - Referenz bleibt?

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
LiLaLaunebär
User
Beiträge: 55
Registriert: Sonntag 11. April 2010, 14:41

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)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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?
LiLaLaunebär
User
Beiträge: 55
Registriert: Sonntag 11. April 2010, 14:41

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...
Snoda
User
Beiträge: 32
Registriert: Mittwoch 1. Februar 2006, 14:34

Am besten so:

Code: Alles auswählen

def foo(value=None):
    if value is None:
        value=[]
Hello world!
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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?
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ist mir bewusst, aber ich ziehe die explizite Form der Perligen vor. Meine 2. Variante hat den "Nachteil" auch, nur damit das nicht untergeht.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

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.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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.
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.
Antworten