2012-08-01 4 views
5

Python-Neuling hier, läuft 2.7.Funktion iteriert mit Druck, aber nicht mit Rückgabe

Ich versuche, ein Programm zu erstellen, das eine Funktion verwendet, um Text zu generieren, und gibt dann den funktionsgenerierten Text in einer Datei aus.

Wenn nur die Funktion in Powershell-Druck (wie folgt aus: http://codepad.org/KftHaO6x), es durchläuft, wie ich will es:

def writecode (q, a, b, c): 
    while b < q: 
     b = b + 1 
     print "v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" %(a,b,c,a,a,a,b,c) 
     print "votes%d_%d.append(v%d_%d_%d)" % (b,c,a,b,c,) 
     print "v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" %(a,c,b,a,a,a,c,b) 
     print "votes%d_%d.append(v%d_%d_%d)" % (c,b,a,c,b) 

writecode (5,1,0,4) 

Wenn die Ausgabe versucht, die Funktion in eine Datei (dies wie: http://codepad.org/8GJpp9QY), es gibt nur 1-Wert, dh nicht iterieren nicht:

def writecode (q, a, b, c): 
    while b < q: 
     b = b + 1 
     data_to_write = "v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" %(a,b,c,a,a,a,b,c) 
     data_to_write_two = "votes%d_%d.append(v%d_%d_%d)" % (b,c,a,b,c,) 
     data_to_write_three = "v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" %(a,c,b,a,a,a,c,b) 
     data_to_write_four = "votes%d_%d.append(v%d_%d_%d)" % (c,b,a,c,b) 
     return data_to_write 
     return data_to_write_two 
     return data_to_write_three 
     return data_to_write_four 

x = writecode (5,1,0,4) 

out_file = open("code.txt", "a") 
out_file.write(x) 
out_file.close() 

Warum ist das und wie kann ich die Ausgabefunktion Iterierte machen (wie es mit Druck der Fall ist)?

+5

Die 'return' Anweisung ** ** beendet die Funktion (wie in den meisten (alle) Sprachen?): Http://docs.python.org/reference/simple_stmts.html#the-return-statement –

+3

Danke an Hamish, dass Sie hier den eigentlichen Code in die Frage gestellt haben ... –

+2

Wenn Sie etwas zurückgehen, scheinen Sie Code-Generierung zu verwenden. Warum führst du den Code nicht direkt aus?Oder etwas zu deiner größeren Aufgabe sagen? –

Antwort

2

In der Version, die Sie zum Schreiben der Datei verwenden, gibt die Funktion nach der ersten Iteration der while-Schleife (über die erste return-Anweisung) zurück. Basierend auf, was Sie haben Sie so etwas wie dies wünschen könnte:

def writecode (q, a, b, c): 
    results = [] 
    while b < q: 
     b = b + 1 
     results.append("v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" % (a,b,c,a,a,a,b,c)) 
     results.append("votes%d_%d.append(v%d_%d_%d)" % (b,c,a,b,c,)) 
     results.append("v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" % (a,c,b,a,a,a,c,b)) 
     results.append("votes%d_%d.append(v%d_%d_%d)" % (c,b,a,c,b)) 
     results.append("") 
    return "\n".join(results) 

x = writecode (5,1,0,4) 

out_file = open("code.txt", "a") 
out_file.write(x) 
out_file.close() 

, die durch Akkumulieren jeder Zeile der Ausgabe in eine Liste arbeitet und gibt dann die einzelnen String mit allen Ergebnissen trat zusammen mit Zeilenumbrüche und einem Newline.

+0

Vielen Dank, der Code, den Sie zur Verfügung gestellt haben, passt genau zu dem, was ich brauchte. Sehr geschätzt! – user1569317

+0

@ user1569317: Gern geschehen. FWIW gibt es wahrscheinlich einfachere Möglichkeiten, um das, was Sie tun, zu erreichen oder zumindest ein wenig lesbarer zu machen. Alles, was ich getan habe, war, Ihnen einen relativ einfachen Weg zu zeigen, was Sie gearbeitet haben. – martineau

1

return existiert sofort die Funktion:

return verlässt den aktuellen Funktionsaufruf mit der Ausdrucksliste (oder None) als Rückgabewert.

Sie müssen die Zeichenfolge bauen, wie Sie gehen (oder, für eine bessere Leistung, eine list von Werten und join am Ende schaffen).

5

Ihr Problem ist, dass man nur return einmal aus einer Funktion:

def test(): 
    return 1 
    return 2 

x = test() 
# x is now 1 

Sie werden entweder yield verwenden wollen oder ein Tupel von Werten zurück:

def this_will_work(): 
    yield 1 
    yield 2 

x = list(this_will_work()) # See below for why we are using list 
# x is now [1, 2] 

def so_will_this: 
    return 1, 2 

x = so_will_this() 
# x is now (1, 2) 

Mit yield verwandelt Ihr Funktion in eine generator, die iteriert werden kann - wenn Sie nur an allen endgültigen Werten interessiert sind, können Sie list verwenden, um den Generator in eine Liste aller Werte umzuwandeln, die Ihr Generator erbringt. Alternativ können Sie die Schleife über for ... in durchlaufen.

0

Eine leichte Abweichung; Ich habe die Formatierung neuer Zeichenfolgen mit benannten Feldern verwendet, die einfacher zu lesen sein sollten.

Beachten Sie, dass Sie einige duplizierte Blöcke generieren (in jedem Fall, in dem b == c zweimal in Ihrer Ausgabe erscheint).

from textwrap import dedent 

codeblock = dedent("""\ 
    v{a}_{b}_{c} = pairwise (caps[{a}],sals[{a}],poss[{a}],poss[{b}],poss[{c}],pos_range) 
    votes{b}_{c}.append(v{a}_{b}_{c}) 
    v{a}_{c}_{b} = pairwise (caps[{a}],sals[{a}],poss[{a}],poss[{c}],poss[{b}],pos_range) 
    votes{c}_{b}.append(v{a}_{c}_{b}) 
""") 

def get_code (q, a, b, c): 
    return ''.join(codeblock.format(a=a, b=b, c=c) for b in xrange(b, q)) 

def main(): 
    with open('code.txt', 'a') as outf: 
     outf.write(get_code(5,1,0,4)) 

if __name__=="__main__": 
    main()