Objekt hat kein Attribut <hier Namen der Funktion einfügen>

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

@Tobs: Das kann nicht sein.

Code: Alles auswählen

from __future__ import print_function


solution = [1, 2, 3]


def spam():
    global solution
    arg = [42]
    if len(arg) < len(solution):
        solution = arg
        print(arg)


def main():
    print('solution before:', solution)
    spam()
    print('solution after:', solution)


if __name__ == '__main__':
    main()
Ausgabe:

Code: Alles auswählen

solution before: [1, 2, 3]
[42]
solution after: [42]
Das heisst irgendwo musst Du nach dem ausführen des ``if``-Blocks erneut etwas an die globale Variable zuweisen.
Tobs
User
Beiträge: 65
Registriert: Sonntag 29. September 2013, 11:11

Ich kann mir das einfach nicht erklären. Ich hab sogar die If-Anweisung auf Dauer-true gestellt, aber hat nix gebracht
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Poste doch bitte einfach mal ein lauffähiges Minimalbeispiel mit deinem Problem. Also eines wo du nicht die Hälfte weglässt, die vermutlich das Problem verursacht. Dann brauch sich der arme BlackJack nicht seitenlang Spekulationen hingeben und du nicht umständlich beschreiben wie du denkst wie das Programm funktioniert.
Tobs
User
Beiträge: 65
Registriert: Sonntag 29. September 2013, 11:11

from Cube import *

Variable = [mit so viel sinnlosen Elementen, so dass die erste Lösung immer genommen wird]
cube = Cube()

...Zeug zum ändern der Attribute...

cube.Finde_Loesung([],0,tiefe) #Halt die Funktion

print(Variable)

und die Ausgabe ist immer die Liste mit den vielen Elementen :-(
Tobs
User
Beiträge: 65
Registriert: Sonntag 29. September 2013, 11:11

Code: Alles auswählen

def Finde_Loesung(self,Zuege,Anzahl,Tiefe):

        print("ICH LEBE!")
        global Loesung

        Loesung = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
    
        Moeg = ["xt","xf","yt","yf","zt","zf"] #Möglichkeiten:
                                         
        for m in Moeg:
    
            #Abbrechen unötiger Durchläufe:
            if Anzahl > 1:
                if m[1] == ("t") and Zuege[len(Zuege)-1][1] == "t": 
                    continue                                              
                if m[0] == Zuege[len(Zuege)-1] and m[1] != Zuege[len(Zuege)-1][1]: 
                    continue                                                      
            if Anzahl > 2:
                if m == Zuege[len(Zuege)-1] and Zuege[len(Zuege)-1] == Zuege[len(Zuege)-2]: 
                    continue                                                                

            self.turn(m) 
            Zuege.append(m) 
            
            if self.is_solved():
                Loesung = Zuege
                print(Zuege)
            else: 
                if Anzahl != Tiefe-1: 
                    self.Finde_Loesung(Zuege,Anzahl+1,Tiefe)
            self.contra_turn(m)
            Zuege.pop()

            
Das hier ist sogar noch die Version, in der er die neue Lösung in jedem Fall übernimmt,
auch wenn die Liste Loesung kürzer als die Liste Zuege ist
Tobs
User
Beiträge: 65
Registriert: Sonntag 29. September 2013, 11:11

Ich habe ja bereits vorher die Frage gestellt, ob es eine Regel in Python ist, dass
eine globale Variable im Programm einen Wert hat, der in der Methode neu definiert werden kann,
aber beim verlassen der Methode wieder auf den Wert außerhalb der Methode zurückgesetzt wird?
Tobs
User
Beiträge: 65
Registriert: Sonntag 29. September 2013, 11:11

Also:

def funktion():

global Variable
Variable = "Wert in Funktion"

Variable = "Wert normal"
funktion()
print(Variable)

----

Ausgabe:
"Wert normal"

???
BlackJack

@Tobs: Ähm Du setzt diese globale Variable doch ganz offensichtlich *selbst* immer wieder auf diesen langen Ausgangswert. Nämlich jedes mal wenn die Methode rekursiv aufgerufen wird.
Tobs
User
Beiträge: 65
Registriert: Sonntag 29. September 2013, 11:11

Das war nur die Darstellung dafür, dass die Variable einen anderen Wert in der Funktion hat,
wenn sie in der Funktion geändert wird. Danach hat sie wieder den Wert den sie außerhalb der Funktion hatte
BlackJack

@Tobs: Das Verhalten was Du beschreibst kann so nicht sein. Wenn da nach dem Ablauf der Methode wieder der Wert vor dem Ablauf der Methode an den globalen Namen gebunden ist, dann muss das irgendwo explizit in Deinem Code, den Du nicht zeigst, passieren. Von alleine passiert das *selbstverständlich nicht*.
Tobs
User
Beiträge: 65
Registriert: Sonntag 29. September 2013, 11:11

Die Variable taucht nur an 4 Stellen auf:

Im Hauptprogramm: -ganz oben Loesung = [Liste mit vielen Elementen]
-ganz unten(print(Loesung))

In der Funktion: -oben: global Loesung
-mitte: Loesung = Zuege <---Zuege ist auch ne Liste
BlackJack

@Tobs: Ähm mir fällt gerade auf Du *veränderst* die Liste. Das ist Dir klar, oder? Vielleicht möchtest Du an der Stelle ja eine *Kopie* der `Zuege`-Liste an `Loesung` binden. Und/oder das beim rekursiven Aufruf machen.
Tobs
User
Beiträge: 65
Registriert: Sonntag 29. September 2013, 11:11

Die Liste mit den Elementen ist praktisch nur ein Platzhalter, der die Bedingung in der späteren Funktion erfüllen soll,
dass, egal wie lang die erste Lösung ist, die Liste immer ein Element länger ist, damit sie übernommen wird.
Er speichert die bisher schnellste Lösung in dieser Variable
BlackJack

@Tobs: Du *veränderst* die *Zuege*-Liste, nachdem Du sie an `Loesung` gebunden hast. Wenn Du die Liste danach veränderst, nun dann veränderst Du die Liste. Und deswegen hast Du am Ende etwas anderes in der Liste stehen als zu dem Zeitpunkt an dem Du sie an das globale `Loesung` gebunden hast. Was im Grunde passiert ist das hier:

Code: Alles auswählen

In [12]: zuege = [1, 2, 3]

In [13]: loesung = zuege

In [14]: zuege.append(42)

In [15]: zuege
Out[15]: [1, 2, 3, 42]

In [16]: loesung
Out[16]: [1, 2, 3, 42]
Du willst eine *Kopie* von `zuege` an `loesung` binden und nicht die *selbe* Liste.
Antworten