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


363

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

def hello():
    return 'Hi :)'

これをコマンドラインから直接実行するにはどうすればよいですか?


21
おそらくあなたはのprint "Hi :)"代わりに意味しましたreturn 'Hi :)'
タマシュ

回答:


567

-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()'

32
Windowsシェルでは、単一引用符ではなく二重引用符が必要であることに注意しました。 $python -c "import foo;foo.hello()"
Arindam Roychowdhury 2016年

6
ファイルがローカルディレクトリまたはPYTHONPATHにない場合はどうなりますか?
コンスタンティン

2
2番目は、より一般的な答えです。スクリプトに複数の顧客関数を定義していて、自分のニーズに応じて1つだけ呼び出す
xappppp

1
どういうわけか、これは私にはうまくいきませんでしたが、代わりprint foo.hello()print(foo.hello())そうしました これがなぜであるかを説明するpythonの知識を持っていないので、誰かが何が起こっているのかを説明できれば、それは非常にありがたいことです
Jasper

2
@Aakanksha説明ありがとうございます。それは間違いなく理にかなっています。かっこを含めるように回答を編集することは正しいように見えますか?そうすれば、私が間違っていなければ、python 2と3の両方と互換性があります。(このような瞬間には、編集の提案をしたいと思いました。)
Jasper

130

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

きちんとしたソリューションの場合、これを使用できます:

if __name__ == '__main__':
    hello()

この方法では、ファイルをインポートしたときではなく、ファイルを実行した場合にのみ関数が実行されます。


3
そして、もしhello()コマンドラインから提供されるべき引数をとったらどうなるでしょう?
匿名

2
その場合sys.argv、メソッドに送信できます。または、helloメソッドからアクセスする
Wolph 2018

3
この回答とインポートfooソリューションの1つの違いは、インポートfooでは、fooを変更せずにfoo内の任意の関数を呼び出すことができることです。
plafratt

それは本当ですが、テストの目的を超えてそのソリューションをお勧めしません
Wolph

@Wolphこの構造でちょっと、別の関数(に含まれていませんhello())を実行してコマンドラインから実行するにはどうすればよいですか?
Souvik Ray

66

python -c 'from myfile import hello; hello()'where myfileは、Pythonスクリプトのベース名に置き換える必要があります。(例:にmyfile.pyなりますmyfile)。

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

def hello():
    print "Hi :)"

if __name__ == "__main__":
    hello()

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

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


2
違いは何であるpython -m foo -c 'foo.bar()'とはpython -c 'import foo; foo.bar()'?最初のケースでは-c引数が無視されているように見える別の動作が発生します。
エイブラム

29

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 __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)

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

括弧をエスケープして、2番目のメソッドへの唯一のパラメーターとしてタプルを渡す最後の例に注意してください。

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


2
それはいいですが、それは質問に対する答えではありません。
Francis Colas、2015年

14
失礼ですが同意できません; それはまさに問題です。彼はファイルから関数をどのように実行するかを尋ねましたが、これはまさにこれが行うことです。
ジョセフガリアード

cmd_folderについて少し説明していますか?
RyanDay 2018年

26

このスニペットをスクリプトの下部に追加します

def myfunction():
    ...


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

実行することで関数を呼び出すことができます

python myscript.py myfunction

これは、コマンドライン引数(関数名の文字列)をlocals現在のローカルシンボルテーブルを持つディクショナリに渡すために機能します。最後の括弧は、関数が呼び出されるようにします。

更新:関数がコマンドラインからパラメーターを受け入れるようにする場合は、次のsys.argv[2]ように渡すことができます。

def myfunction(mystring):
    print mystring


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

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


このメソッドが関数のパラメーターを受け入れることは可能ですか?などmyfunction(12)
メジャーメジャー

@MajorMajor私はこれを行う方法を含めるように回答を更新しました
Noam Hacker

ライブ制作でこれを行うのは危険ですか?単体テストとして作成したい。
アルディ

9

これを少しだけ簡単にして、モジュールを使用してみましょう...

試してください: pip install compago

次に書いてください:

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()

次に、次のように使用します。

$ python test.py hello
hi there!

$ python test.py goodbye
see ya later.

注:現在、Python 3にはバグがありますが、Python 2で問題なく動作します。

編集:私の意見では、さらに優れたオプションは、関数の引数も簡単に渡すことができるGoogleによるモジュールfireです。とともにインストールされpip install fireます。彼らのGitHubから:

簡単な例を示します。

import fire

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

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

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

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

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

+1。Fireには、スクリプトを変更せずに関数を呼び出す方法もありますpython -m fire file_name method_name。また、argparserも組み込まれています。
user3265569

6

興味深いことに、コマンドラインコンソールに出力することや、その他のpython操作を実行することが目的である場合は、次のように入力をpythonインタープリターにパイプすることができます。

echo print("hi:)") | python

パイプファイルと同様に

python < foo.py

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

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

foo.py with hello()の例を考えると、これは上記のアイデアで使用できる方法です。 echo import foo;foo.hello() | python
Arindam Roychowdhury 2016年

このメソッドでコマンドライン引数を渡す方法はありますか?
sparkonhdfs 2017

1
FWIW、以下では、わずかに第三の例のためにクリーナーである:echo 'print("hi:)")' | python
user3166580


4

コマンドラインでさまざまなpythonユーティリティ(範囲、文字列など)を使用する必要があり、そのためのツール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

1

常にコマンドを使用してコマンドライン上でのpythonを入力するためのオプションですパイソン

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

次にexample_file.hello()でコマンドを実行します

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

たぶん単一コマンドほど便利ではないかもしれませんが、コマンドラインからファイルにテキストを送信するための適切なクイックフィックスであり、Pythonを使用してファイルを呼び出して実行することができます。


1

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

以下は、関数の定義を含む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のフルパス "from Odd_Even_function import OE; OE(100)"

ありがとう。


0

この関数は、渡されない値を返すため、コマンドラインから実行できません。返品を削除して、代わりに印刷を使用できます


-2

使用のpython-Cの(ツールをPIPのpython-Cインストール)して、単純に書きます:

$ python-c foo 'hello()'

または、Pythonファイルに関数名の衝突がない場合:

$ python-c 'hello()'

-2

最初に、彼らが言ったように関数を呼び出す必要があります。そうしないと、機能は出力に何も表示しません。その後、ファイルを保存し、ファイルのフォルダーに右クリックして「ファイルのコピー」をクリックしてファイルのパスをコピーします。ターミナルに移動して、次のように記述します。-cd "ファイルのパス"-python "たとえば、ファイル名(main.py)"その後、コードの出力が表示されます。


-4

Spyderをインストールして、人生を楽にしてください。ファイルを開いて実行します(緑色の矢印をクリックします)。その後、hello()メソッドが定義され、IPythonコンソールに認識されるので、コンソールから呼び出すことができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.