2015-05-25 9 views
7

dies ist meine erste Frage, so sorry ... ich ein Anfänger mit Python und Codierung im Allgemeinen bin, und ich wollte eine Klasse namens ‚Karte‘ erstellen, die die folgenden Klassenvariablen haben würden :Python Anfänger Klasse Variable Fehler

class Map: 
    height = 11 
    width = 21 

    top = [['#']*width] 
    middle = [['#']+[' ']*(width-2)+['#'] for i in range(height-2)] 
    field = top + middle + top 

b = Map() 

Shell: 
>>> middle = [['#']+[' ']*(width-2)+['#'] for i in range(height-2)] 
    NameError: name 'width' is not defined 

Wenn ich die Variablen außerhalb der Klasse setzt, funktioniert es. Was mache ich falsch ??

Danke für die Hilfe.

+2

Haben Sie das Lernprogramm [Klassen] (https://docs.python.org/2/tutorial/classes.html) durchlaufen? – bereal

+0

b.breite? b.height? Da du außerhalb der Klasse bist, die Karte. Sehen Sie diesen Beitrag es wird Ihnen helfen, besser zu verstehen: http://stackoverflow.com/questions/68645/static-class-variables-in-python – Alex

+1

Funktioniert auch für mich – Ladmerc

Antwort

7

Vom docs:

Namen beziehen sich auf Objekte. Namen werden durch Namensbindungsoperationen eingeführt. Jedes Auftreten eines Namens im Programmtext bezieht sich auf die Bindung des im innersten Funktionsblock enthaltenen Namens, der die Verwendung enthält.

Ein Block ist ein Stück Python Programmtext, die als Einheit ausgeführt wird. Die folgenden Blöcke sind: ein Modul, ein Funktionskörper und eine Klassendefinition. Jeder interaktiv eingegebene Befehl ist ein Block. Eine Skriptdatei (eine Datei, die dem Interpreter als Standardeingabe oder als Befehlszeilenargument für den Interpreter angegeben wird) ist ein Codeblock. Ein Skriptbefehl (ein Befehl, der in der Interpreter-Befehlszeile mit der Option '-c' angegeben wird) ist ein Codeblock. Das String-Argument, das an die integrierten Funktionen eval() und exec() übergeben wird, ist ein Codeblock.

Ein Codeblock ist in einem Ausführungs Rahmen ausgeführt. Ein Rahmen enthält einige Verwaltungsinformationen (die zum Debuggen verwendet werden) und bestimmt, wo und wie die Ausführung fortgesetzt wird, nachdem die Ausführung des Codeblocks abgeschlossen wurde.

A Umfang definiert die Sichtbarkeit eines Namens innerhalb eines Blocks. Wenn eine lokale Variable in einem Block definiert ist, enthält ihr Bereich diesen Block. Wenn die Definition in einem Funktionsblock auftritt, erstreckt sich der Geltungsbereich auf alle Blöcke innerhalb des definierenden Bereichs, es sei denn, ein enthaltener Block führt eine andere Bindung für den Namen ein. Der Geltungsbereich der in einem Klassenblock definierten Namen ist auf den Klassenblock beschränkt; Es erstreckt sich nicht auf die Codebausteine ​​von Methoden - dies schließt auch Vervollständigungen und Generatorausdrücke ein, da sie unter Verwendung eines Funktionsumfangs implementiert sind. Dies bedeutet, dass die folgenden fehl:

class A: 
    a = 42 
    b = list(a + i for i in range(10)) 

Liste Comps in python3 ihren eigenen Anwendungsbereich haben, im Gegensatz zu python2 in dem der Code funktionieren würde, wie es ist.

Wenn Sie das folgende Beispiel mit python2 nehmen, können Sie sehen, wie Variablen, um den Umfang der Liste comp undichte könnten einige Probleme verursachen:

class A: 
    a = 42 
    b = [a for a in range(10)] 

a = A() 

print(a.a) 
9 

Sie haben ein paar Optionen, könnten Sie __init__ Erstellen Instanz Attribute verwenden :

class Map: 
    def __init__(self): 
     self.height = 11 
     self.width = 21 
     self.top = [['#']*self.width] 
     self.middle = [['#']+[' ']*(self.width-2)+['#'] for i in range(self.height-2)] 
     self.field = self.top + self.middle + self.top 
m=Map() 
print(m.field) 

Unter Verwendung eines Verfahrens:

class Map: 
    @staticmethod 
    def meth(): 
     height = 11 
     width = 21 
     top = [['#']*width] 
     middle = [['#']+[' ']*(width-2)+['#'] for i in range(height-2)] 
     field = top + middle + top 
     return field 

b = Map() 


print(b.meth()) 

Was Sie wählen, hängt wirklich davon ab, was Sie tun möchten.

+0

So ... die "for" -Schleifenfunktion innerhalb der Liste hat keinen Zugriff auf die Breitenvariable? – Cookiesforhelp

+0

@Cookiesforhelp, ja, genau. –

+0

Vielen Dank für Ihre Zeit und die Links aber, eine letzte Frage im Python2-Beispiel verliert die Variable "Byte-Daten" zu einer anderen Zahl, weil das seltsam ist – Cookiesforhelp

0

müssen Sie b.width und b.height verwenden, um die Membervariablen beziehen definieren. Siehe Beitrag für eine Erklärung über das Mitglied Zugriff auf Variablen - Accessing a class' member variables in Python?

+0

Dies ist falsch und nicht tatsächlich auf das Problem überhaupt bezogen, der Fehler passiert, bevor die Instanz erstellt wird –