2010-11-21 11 views
1

vielleicht ist der Titel nicht sehr klar, lassen Sie mich näher darauf eingehen.führen Sie eine Funktion (aus einer .py-Datei) von einer Linux-Konsole

Ich habe ein Python-Skript, das eine ppm-Datei öffnet, einen ausgewählten Filter (Rotationen ...) anwendet und ein neues Bild erzeugt. Bis hier läuft alles gut.

aber ich möchte die gleiche Sache über eine Linux-Konsole tun:

ppmfilter.py ROTD /path/imageIn.ppm /path/imageOut.ppm

hier ROTD der Name der Funktion ist, die eine Drehung anwenden.

Ich weiß nicht, wie das geht, ich bin auf der Suche nach einer Bibliothek, die mir erlauben wird, dies zu tun.

wir freuen uns auf Ihre Hilfe.

PS: Ich verwende Python 2.7

Antwort

7

Es ist eine relativ einfache Art und Weise:

Sie können die globalen Namen bestimmen (Funktionen, Variablen usw.) mit der Verwendung von 'globals()'. Dies gibt Ihnen ein Wörterbuch aller globalen Symbole. Sie müssen nur den Typ überprüfen (mit Typ() und den Modultypen), und wenn es eine Funktion ist, können Sie es mit sys.argv nennen:

import types 
import sys 

def ROTD(infile, outfile): 
    # do something 

if __name__ == '__main__': 
    symbol = globals().get(sys.argv[1]) 
    if hasattr(symbol, '__call__'): 
     symbol(*sys.argv[2:]) 

Damit wird das Programm Argument übergeben (mit Ausnahme der Dateiname und der Befehlsname) für die Funktion.

EDIT: Bitte, vergessen Sie nicht die Fehlerbehandlung. Ich habe es aus Gründen der Klarheit weggelassen.

+1

Ich würde ein 'if __name__ ==" __main __ "' hinzufügen, damit Sie das Modul immer noch importieren können, ohne es zu versuchen. Außerdem sollten Sie 'sys.argv [1]', nicht 'sys.argv [0]' (welches der Name des Skripts ist) nachschlagen. –

+0

@Thomas: Danke für die Tipps, ich habe es behoben. – terminus

+1

Kühl.Um noch pythischer zu sein, könnten Sie 'if hasattr (symbol," __call __ ")' testen, anstatt nach dem Funktionstyp zu suchen. Auf diese Weise können Sie eine Klasse (oder ein anderes aufrufbares Objekt) auf dieselbe Weise aufrufen und einen Import speichern. –

1

Verwenden main() Funktion:

def main() 
    # call your function here 

if __name__ == "__main__": 
    main() 
+0

Außerdem müssen Sie '#!/Usr/bin/env python' (oder ähnlich) als erste Zeile Ihrer Datei hinzufügen, es ausführbar machen und, wahrscheinlich im Block 'if __name__ ...', parsen die Befehlszeilenargumente und beschäftigen Sie sich mit ihnen (wahrscheinlich, indem Sie sie in Ihre Funktion übergeben). –

0

Sie können in Ihrem ppmfilter.pymain Abschnitt tun dies definieren:

if __name__ == "__main__": 
    import sys 
    ROTD(sys.argv[1], sys.argv[2]) # change according to the signature of the function 

und nennen es: python ppmfilter.py file1 file2

Sie auch python -c im Verzeichnis ausführen können, die Sie * .py-Datei enthält:

python -c "import ppmfilter; ppmfilter.ROTD('/path/to/file1', '/path/to/file2')" 
1

Eine schöne Möglichkeit wäre, ein großes Wörterbuch zu definieren {alias: function} in deinem Modul. Zum Beispiel:

actions = { 
    'ROTD': ROTD, 
    'REFL': reflect_image, 
    'INVT': invIm, 
} 

Sie bekommen die Idee. Nehmen Sie dann das erste Befehlszeilenargument und interpretieren Sie es als Schlüssel dieses Wörterbuchs, indem Sie actions[k] auf die restlichen Argumente anwenden.