2010-10-21 24 views
193

Run Ho seguito il codice nel mio file:Python: la funzione dalla riga di comando

def hello(): 
    return 'Hi :)' 

Come dovrei eseguire questo dalla riga di comando?

+9

Probabilmente intendevi 'stampa" Ciao :) "' invece di 'ritorno 'Ciao :)''. –

+0

Duplicato di tutti questi: http://stackoverflow.com/search?q=%5Bpython%5D+run+command+line –

risposta

318

Con il (comando) argomento -c (supponendo che il file è denominato foo.py):

$ python -c 'import foo; print foo.hello()' 

In alternativa, se non si cura di inquinamento dello spazio dei nomi:

$ python -c 'from foo import *; print hello()' 

E il via di mezzo:

$ python -c 'from foo import hello; print hello()' 
+12

Ho notato che su Windows Shell, hai bisogno di un doppio preventivo invece di singolo. '$ python -c" import foo; foo.hello() "' –

+1

Cosa succede se il file non si trova nella directory locale o sul PYTHONPATH? – Konstantin

+0

Su Ubuntu Linux è necessario utilizzare anche virgolette doppie se si esegue il comando da un'applicazione Qt, ad esempio. –

38

python -c 'from myfile import hello; hello()' dove myfile deve essere sostituito con il nome base dello script Python. (Ad esempio, myfile.py diventa myfile).

Tuttavia, se hello() è il vostro punto di ingresso "permanente" principale nello script Python, poi la solita modo per farlo è la seguente: si

def hello(): 
    print "Hi :)" 

if __name__ == "__main__": 
    hello() 

Questo permette di eseguire lo script semplicemente eseguendo python myfile.py oppure python -m myfile.

Qualche spiegazione qui: __name__ è una variabile speciale Python che contiene il nome del modulo in corso di esecuzione, tranne quando il modulo viene avviato dalla riga di comando, nel qual caso diventa "__main__".

+0

Qual è la differenza tra 'python -m foo -c 'foo.bar()'' e 'python -c 'importa foo; foo.bar() ' '? Ottengo comportamenti diversi in cui sembra che l'argomento -c venga ignorato nel primo caso. – Abram

69

Basta mettere hello() da qualche parte sotto la funzione ed eseguirà quando si fanno python your_file.py

Per una soluzione più ordinato è possibile utilizzare questo:

if __name__ == '__main__': 
    hello() 

In questo modo la funzione viene eseguita solo se si esegue il file, non quando si importa il file.

+1

questa dovrebbe essere la risposta corretta – zon7

+0

E se 'ciao()' prende gli argomenti che dovrebbero essere forniti dalla riga di comando? – Anonymous

+0

In questo caso è possibile inviare 'sys.argv' al metodo. O accedervi dal metodo Hello – Wolph

0

Questa funzione non può essere eseguita dalla riga di comando poiché restituisce un valore che andrà non diretto. È possibile rimuovere il ritorno e l'uso di stampa invece

0

Si è sempre un'opzione per entrare pitone nella riga di comando con il comando python

quindi importare il file in modo importazione example_file

quindi eseguire il comando con example_file.hello()

questo modo si evita la funzione di copia .pyc strano che affiora ogni volta che si esegue python -c ecc

Forse non conveniente come un comando singolo, ma una buona soluzione rapida per inviare un messaggio di testo da una riga di comando e consente di utilizzare python per chiamare ed eseguire il file.

0

Qualcosa di simile a questo: call_from_terminal.py

# call_from_terminal.py 
# Ex to run from terminal 
# ip='"hi"' 
# python -c "import call_from_terminal as cft; cft.test_term_fun(${ip})" 
# or 
# fun_name='call_from_terminal' 
# python -c "import ${fun_name} as cft; cft.test_term_fun(${ip})" 
def test_term_fun(ip): 
    print ip 

Questo funziona in bash.

$ ip='"hi"' ; fun_name='call_from_terminal' 
$ python -c "import ${fun_name} as cft; cft.test_term_fun(${ip})" 
hi 
17

Ho scritto un breve script Python che è richiamabile da una riga di comando bash. Prende il nome del modulo, classe e metodo che si desidera chiamare e i parametri che si desidera passare. Io lo chiamo PyRun e lasciato fuori l'estensione .py e reso eseguibile con chmod + x PyRun modo che posso chiamare rapidamente come segue:

./PyRun PyTest.ClassName.Method1 Param1 

Salva questo in un file chiamato PyRun

#!/usr/bin/env python 
#make executable in bash chmod +x PyRun 

import sys 
import inspect 
import importlib 
import os 

if __name__ == "__main__": 
    cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile(inspect.currentframe()))[0])) 
    if cmd_folder not in sys.path: 
     sys.path.insert(0, cmd_folder) 

    # get the second argument from the command line  
    methodname = sys.argv[1] 

    # split this into module, class and function name 
    modulename, classname, funcname = methodname.split(".") 

    # get pointers to the objects based on the string names 
    themodule = importlib.import_module(modulename) 
    theclass = getattr(themodule, classname) 
    thefunc = getattr(theclass, funcname) 

    # pass all the parameters from the third until the end of 
    # what the function needs & ignore the rest 
    args = inspect.getargspec(thefunc) 
    z = len(args[0]) + 2 
    params=sys.argv[2:z] 
    thefunc(*params) 

Ecco un modulo di esempio per mostrare come funziona. Questo viene salvato in un file chiamato PyTest.py:

class SomeClass: 
@staticmethod 
def First(): 
    print "First" 

@staticmethod 
def Second(x): 
    print(x) 
    # for x1 in x: 
    #  print x1 

@staticmethod 
def Third(x, y): 
    print x 
    print y 

class OtherClass: 
    @staticmethod 
    def Uno(): 
     print("Uno") 

Provare a eseguire questi esempi:

./PyRun PyTest.SomeClass.First 
./PyRun PyTest.SomeClass.Second Hello 
./PyRun PyTest.SomeClass.Third Hello World 
./PyRun PyTest.OtherClass.Uno 
./PyRun PyTest.SomeClass.Second "Hello" 
./PyRun PyTest.SomeClass.Second \(Hello, World\) 

Nota l'ultimo esempio di sfuggire le parentesi per passare una tupla come unico parametro per la seconda metodo.

Se si passano troppo pochi parametri per ciò che il metodo richiede, si ottiene un errore. Se ne passi troppi, ignora gli extra. Il modulo deve essere nella cartella di lavoro corrente, mettere PyRun può essere ovunque nel tuo percorso.

+2

È bello, ma non è davvero una risposta alla domanda. –

+8

Mi permetto di dissentire; è esattamente la domanda. Ha chiesto come si esegue una funzione da un file e questo è esattamente ciò che fa. –

+0

Puoi spiegare che cosa sta facendo il bit su cmd_folder? – RyanDay

2

Se si installa il pacchetto RUNP con pip install runp la sua una questione di esecuzione:

runp myfile.py hello

È possibile trovare il repository a: https://github.com/vascop/runp

4

È interessante notare che, se l'obiettivo era quello di stampare su console della riga di comando o eseguire qualche altra operazione Python minuto, è possibile reindirizzare l'input nell'interprete python in questo modo:

echo print("hi:)") | python 

così come i file di tubi ..

python < foo.py 

* Si noti che l'estensione non deve essere .py per la seconda al lavoro. ** Si noti inoltre che per bash potrebbe essere necessario per sfuggire ai personaggi

echo print\(\"hi:\)\"\) | python 
+0

Considerando l'esempio di foo.py con hello(), questo è il modo in cui si può usarlo con l'idea di sopra. 'echo import foo; foo.hello() | python' –

+0

C'è un modo per passare gli argomenti della riga di comando con questo metodo? – iamseiko

+0

FWIW, il seguente è leggermente più pulito per il terzo esempio: 'echo 'print (" hi :) ")' | python' – user3166580

1

ho avuto un requisito di utilizzare vari programmi di utilità di Python (range, stringhe, ecc) sulla riga di comando e avevo scritto lo strumento pyfunc specificamente per quello. Puoi usarlo per arricchire la tua esperienza di utilizzo da riga di comando:

$ pyfunc -m range -a 1 7 2 
1 
3 
5 

$ pyfunc -m string.upper -a test 
TEST 

$ pyfunc -m string.replace -a 'analyze what' 'what' 'this' 
analyze this 
2

Facciamo un po 'più facile su noi stessi e basta usare un modulo ...

Prova: pip install compago

quindi scrivere:

import compago 
app = compago.Application() 

@app.command 
def hello(): 
    print "hi there!" 

@app.command 
def goodbye(): 
    print "see ya later." 

if __name__ == "__main__": 
    app.run() 

Quindi utilizzare in questo modo:

$ python test.py hello 
hi there! 

$ python test.py goodbye 
see ya later. 

Nota: C'è un bug in Python 3, al momento, ma funziona alla grande con Python 2.

Modifica: Un'opzione ancora migliore, secondo me, è il modulo fire di Google che rende semplice anche passare gli argomenti della funzione. È installato con pip install fire. Dal loro GitHub:

Ecco un semplice esempio.

import fire 

class Calculator(object): 
    """A simple calculator class.""" 

    def double(self, number): 
    return 2 * number 

if __name__ == '__main__': 
    fire.Fire(Calculator) 

Poi, dalla riga di comando, è possibile eseguire:

python calculator.py double 10 # 20 
python calculator.py double --number=15 # 30 
0

Utilizzare lo strumento python-c (pip installare python-c) e poi semplicemente scrivere:

$ python-c foo 'hello()' 

o nel caso in cui non ci siano conflitti di nomi di funzione nei file Python:

$ python-c 'hello()' 
Problemi correlati