2016-11-11 2 views
0

Ich wurde von etwas seltsames Verhalten in Python 3.5.2 festgefahren. Ich habe eine Klasse Foo und möchte ein Stück Code nur einmal für alle Instanzen ausführen. Dieser Code befindet sich direkt unter der class-Anweisung.Python 3.5.2: "Name nicht definiert", wenn das Verzeichnis nicht leer ist

import os 

class Foo: 

    path = "annotations/" 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 

    def __init__(self, x): 
     # do something 
     1+1 

Wenn Sie diesen Code runing, wird folgende Fehlermeldung angezeigt, wenn das annotations Verzeichnis nicht leer (eine leere Datei genügt) ist

Traceback (most recent call last): 
    File "foo.py", line 3, in <module> 
    class Foo: File "foo.py", line 6, in Foo 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] File "foo.py", line 6, in <listcomp> 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 
NameError: name 'path' is not defined 

tritt jedoch kein Fehler, wenn die annotations/ leer. Warum? Dieses seltsame Verhalten tritt nur auf, wenn die Einzeilen-for-Schleife verwendet wird.

Ich benutze Python 3.5.2. Wenn der obige Code mit Python 2.7.12 ausgeführt wird, wird der Fehler nicht angezeigt.

+0

Kann nicht auf MacOs Python 3.5.2 reproduzieren. Jedenfalls würde ich vorschlagen, den Wert für 'Dateien' in einer Funktion zu berechnen, nicht innerhalb einer' Klassen'-Definition - was Sie tun, ist hässlich. Versuchen Sie, Python zu aktualisieren/neu zu installieren. – warvariuc

+0

Ich benutze Python 3.5.2. auf einem Ubuntu 16.04-System. Dies scheint mir eine normale Methode zu sein, statischen Code zu einer Klasse hinzuzufügen. Warum sollte das hässlich sein? Wenn niemand eine befriedigende Lösung präsentiert, werde ich wahrscheinlich versuchen, Python neu zu installieren. – null

+1

Sie erhalten einen 'NameError', weil im * verschachtelten Bereich eines Listenverständnisses * der Name' path' nicht sichtbar ist. Aber nur die Verwendung in der if-Anweisung, nicht die äußerste für iterable Quelle (weil das außerhalb des Listenverständnisses berechnet wird), und die if-Anweisung wird nur verwendet, wenn tatsächlich Elemente im Iterator zu testen sind. Siehe das Duplikat. –

Antwort

0

Wenn ich verstanden habe, zuerst haben Sie nicht den "Annotations" -Pfad, dann machen Sie den "Annotations" -Pfad und funktioniert. Wenn ja, macht es Sinn, denn das Skript versucht, den "Annotations" Pfad zu lesen, aber der Pfad existiert nicht!

Sie können etwas tun:

if os.path.exists('annotations/'): 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 

Oder Kraft den Weg machen:

if not os.path.exists('annotations/'): 
    os.mkdir('annotations/') 
files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 
+0

Das ist nicht das Problem. Das Verzeichnis existiert. Siehe meine Bearbeitung über – null

0

Wenn Sie Pfad definiert ist, keine Möglichkeit, Sie NameError bekommen - man Sie erwähnt haben. Laufen kann es Ihnen geben:

OSError: [Errno 2] No such file or directory: 'annotations/'

Falls es kein Verzeichnis mit dem Namen annotations


das Szenario zu behandeln - Sie müssen Verzeichnis erstellen, wenn sie nicht da ist (wie Hugo erwähnt):

import os 

class Foo: 

    path = "annotations/" 
    if not os.path.exists('annotations/'): 
     os.mkdir('annotations/') 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 

    def __init__(self, x): 
     # do something 
     1+1 


if __name__ == "__main__": 
    obj = Foo(1) 
    print 'hello' 

Der Ausgang - arbeitete absolut in Ordnung, dh erstellt auch die Anmerkungen dir ectory selbst:

[[email protected] so_tmp]$ ls 
[[email protected] so_tmp]$ python ../path_issue.py 
hello 
[[email protected] so_tmp]$ ls 
annotations 
[[email protected] so_tmp]$ 
+0

Ich bekomme einen NameError. Ich habe keine Ahnung, warum das passiert. Dies geschieht nur, wenn das Zielverzeichnis nicht leer ist (siehe oben Bearbeiten). – null

Verwandte Themen