web-dev-qa-db-ja.com

コマンドラインから関数を実行する

私はこのコードを持っています:

def hello():
    return 'Hi :)'

これをコマンドラインから直接実行する方法を教えてください。

282
Steven

-c (コマンド) 引数を使用する(ファイルの名前がfoo.pyであると仮定します)。

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

あるいは、名前空間の汚染を気にしないのであれば、

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

そして真ん中は:

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

hello()を関数の下のどこかに置くだけで、python your_file.pyを実行したときに実行されます。

より良い解決策のためにあなたはこれを使うことができます:

if __== '__main__':
    hello()

そうすれば、ファイルをインポートしたときではなく、ファイルを実行したときにだけ関数が実行されます。

105
Wolph

python -c 'from myfile import hello; hello()'ここでmyfileはあなたのPythonスクリプトのベース名に置き換えなければなりません。 (例:myfile.pymyfileになります)。

ただし、hello()がPythonスクリプトの「永続的」なメインエントリポイントである場合、これを行う通常の方法は次のとおりです。

def hello():
    print "Hi :)"

if __== "__main__":
    hello()

これにより、python myfile.pyまたはpython -m myfileを実行するだけでスクリプトを実行できます。

__name__は現在実行されているモジュールの名前を保持する特別なPython変数です。 モジュールがコマンドラインから起動された場合は を除いて、"__main__"になります。

49
Tamás

私はbashのコマンドラインから呼び出せる簡単で小さなPythonスクリプトを書きました。呼び出したいモジュール、クラス、メソッドの名前と、渡したいパラメータを取ります。私はそれをPyRunと呼び、.py拡張子を省き、chmod + x PyRunで実行可能にしました。

./PyRun PyTest.ClassName.Method1 Param1

これをPyRunというファイルに保存してください。

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

import sys
import inspect
import importlib
import os

if __== "__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)

これがどのように機能するかを示すためのサンプルモジュールです。これは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")

これらの例を実行してみてください。

./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\)

Secondメソッドの唯一のパラメータとしてTupleを渡すために括弧をエスケープする最後の例に注意してください。

メソッドが必要とするものに対してあまりにも少ないパラメータを渡すと、エラーになります。あなたがあまりにも多くを渡した場合、それはエキストラを無視します。モジュールは現在の作業フォルダになければなりません、PyRunはあなたのパスのどこにでも置くことができます。

23

このスニペットをスクリプトの最後に追加してください

def myfunction():
    ...


if __== '__main__':
    globals()[sys.argv[1]]()

あなたは今実行することによってあなたの関数を呼び出すことができます

python myscript.py myfunction

これは、コマンドライン引数(関数名の文字列)を現在のローカルシンボルテーブルを持つ辞書であるlocalsに渡しているためです。最後の括弧は関数を呼び出すようにします。

update: もしあなたがコマンドラインからパラメータを受け付けるようにしたいのなら、sys.argv[2]を次のように渡してください。

def myfunction(mystring):
    print mystring


if __== '__main__':
    globals()[sys.argv[1]](sys.argv[2])

このようにしてpython myscript.py myfunction "hello"を実行するとhelloが出力されます。

9
Noam Hacker

私たち自身でこれをもう少し簡単にして、ただモジュールを使用しましょう。

試してみてください:pip install compago

それから書く:

import compago
app = compago.Application()

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

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

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

それならこんな風に使ってください:

$ python test.py hello
hi there!

$ python test.py goodbye
see ya later.

注:現時点ではPython 3には bug がありますが、Python 2ではうまく機能します。

編集: 私の意見では、グッドのモジュール fire を使うのがさらに良い選択肢です。これにより、関数の引数も簡単に渡すことができます。 pip install fireと一緒にインストールされます。彼らのGitHubから:

これは簡単な例です。

import fire

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

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

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

次に、コマンドラインから次のコマンドを実行します。

python calculator.py double 10  # 20
python calculator.py double --number=15  # 30
5
Charles Clayton

面白いことに、コマンドラインコンソールに出力すること、またはその他の細かいpython操作を実行することが目的であれば、入力を次のようにpythonインタプリタに渡すことができます。

echo print("hi:)") | python

パイプファイルと同様に。

python < foo.py

*拡張子が2番目に機能するために.pyである必要はないことに注意してください。 **またbashのためにあなたは文字をエスケープする必要があるかもしれないことに注意してください

echo print\(\"hi:\)\"\) | python
5
Torie J

pip install runpを指定してrunpパッケージをインストールすると、実行の問題になります。

runp myfile.py hello

リポジトリは次の場所にあります。 https://github.com/vascop/runp

5
vascop

私はコマンドラインでさまざまなpythonユーティリティ(range、stringなど)を使う必要があり、そのために pyfunc というツールを書いていました。あなたはあなたにコマンドライン使用経験を豊かにするためにそれを使うことができます:

 $ 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
4
Saurabh Hirani

このようなもの: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

これはbashで機能します。

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

コマンドラインで python というコマンドでpythonを入力することは常にオプションです。

次にファイルをインポートします。 import example_file

それから example_file.hello() を指定してコマンドを実行します。

これにより、python -cなどを実行するたびに生成される奇妙な.pycコピー機能が回避されます。

たぶん、シングルコマンドほど便利ではないかもしれませんが、コマンドラインからファイルをテキスト化するための良い素早い修正で、pythonを使ってファイルを呼び出して実行することを可能にします。

1
user2495144

以下は、関数の定義を含むOdd_Even_function.pyファイルです。

def OE(n):
    for a in range(n):
        if a % 2 == 0:
            print(a)
        else:
            print(a, "ODD")

今コマンドプロンプトから同じことを呼ぶために今私のために働いたオプションがあります。

オプション1 exeの絶対パス\ python.exe -c "import Odd_Even_function; Odd_Even_function.OE(100)"

オプション2 exe\python.exe -cのフルパス "Odd_Even_function import OEから; OE(100)"

ありがとう。

1
moxit mehta

この関数はコマンドラインから実行することはできません。手を加えないで値が返されるためです。あなたはリターンを削除し、代わりにprintを使うことができます

0
Shubham