2016-07-25 11 views
0

Ich bin neu in Python und lerne Eingabe/Ausgabe. Im Moment versuche ich, Attribute zu einem Objekt aus einer Datei hinzuzufügen, die ich über die Befehlszeile eingegeben habe.Initialisiere ein Python-Objekt über die Kommandozeileneingabe

Zum Beispiel möchte ich folgendes ausführen: den Inhalt der Datei 06

$ /...filepath.../ cat 06 
7 
4 5 2 7 88 2 1 

zu myCode.py$ /...filepath.../ python3 myCode.py < 06 passieren. Sowohl myCode.py als auch 06 befinden sich im selben Verzeichnis.

Ich versuche, ein MyClass Objekt aus einem Kommandozeilenaufruf mit Attributen zu erstellen sein, wie folgt:

## myCode.py ## 

# create class 
class MyClass(object): 
    def __init__(self): 
    self._num_one = int(sys.stdin.readline())  
    self._num_many = [int(x) for x in sys.stdin.readline().split()] 

# print attributes 
print(MyClass()._num_many) 
print(MyClass()._num_one) 

aber ich erhalte die folgenden Fehler ValueError: invalid literal for int() with base 10: '' für self._num_one aber bin in der Lage tor Druck self._num_many und Ich bin mir nicht sicher warum. Wenn ich die Reihenfolge self._num_one und self.num_many vertausche, kann ich self._num_one bekommen. Da 06 nur zwei Zeilen lang ist, gibt es eine erste Zeile, die ich anfangs nicht lese? Warum kann ich nur eines der beiden Attribute drucken und wie würde ich beides drucken?

Vielen Dank.

+1

Es wird allgemein als schlechter Entwurf angesehen, komplexe Operationen wie IO in einem Klasseninitialisierer zu haben. In diesem Fall wird jedes Mal, wenn Sie ein neues Objekt erstellen möchten, von stdin gelesen. Das macht das Testen viel schwieriger. Besser, eine "Factory-Funktion" zu verwenden, um stdin zu lesen, die Eingabe zu analysieren und dann die Klasse mit den richtigen Typen zu instanziieren. – Keith

Antwort

0

einige Probleme mit Ihrem Code Es gibt, die es von nicht mehr funktioniert.

Als erstes müssen Sie Leerzeichen davor und danach entfernen, wenn Sie die Eingabedatei eine Zeile nach der anderen lesen. Dies bedeutet einen Aufruf an die .strip() Methode nach .readline(). Sie erhalten die ValueError, weil int() nicht numerische Zeichenfolge nicht verarbeiten kann.

>>> int('x') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: invalid literal for int() with base 10: 'x' 
>>> int(' ') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: invalid literal for int() with base 10: ' ' 
>>> int('\n') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: invalid literal for int() with base 10: '\n' 
>>> int('1') 
1 

So wird der Code

class MyClass(object): 
    def __init__(self): 
     self._num_one = int(sys.stdin.readline().strip()) 
     self._num_many = [int(x) for x in sys.stdin.readline().strip().split()] 

Zweitens, wenn Sie MyClass() tun instanziiert es ein neues Objekt. Wenn ich den Code richtig verstehe, erwartet er zwei Zeilen zweimal (4 Zeilen insgesamt) zu lesen. Angesichts der Eingabedatei gehe ich davon aus, dass Sie daran interessiert sind, ONE Objekt instanziieren. Deshalb instanziieren wir eins und markieren es mit einer Variable und verwenden diese Referenz später.

instantiatedObject = MyClass() 
print(instantiatedObject._num_many) 
print(instantiatedObject._num_one) 
0

Nur weil Ihr Eingabestream kein int ist, es ist eine Zeichenfolge mit Leerzeichen und "\ n" Trennzeichen, müssen Sie zuerst an diesen Dingen arbeiten.

Die schnelle und einfache Möglichkeit, Ihren Code zu so etwas wie dieses (nicht getestet) ändert sich:

self._num_one = int("".join(sys.stdin.readline().split()))