从命令行运行功能


363

我有以下代码:

def hello():
    return 'Hi :)'

我将如何直接从命令行运行它?


21
可能是您的意思print "Hi :)"不是return 'Hi :)'
塔玛斯

Answers:


566

使用-c (command)参数(假设您的文件名为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 Shell上,您需要双引号而不是单引号。 $python -c "import foo;foo.hello()"
Arindam Roychowdhury '16

6
如果文件不在本地目录或PYTHONPATH中怎么办?
康斯坦丁

2
第二个是更笼统的答案。我有一个定义了多个客户功能的脚本,并且仅根据我的需要调用一个功能
xappppp '18

1
由于某种原因,这对我不起作用,而用代替print foo.hello()print(foo.hello())。我没有python知识来解释为什么会这样,所以如果其他人可以解释会发生什么,那将不胜感激
Jasper

2
@Aakanksha感谢您的解释,这绝对是有道理的。编辑答案以包含括号似乎正确吗?如果我没记错的话,这将使其与python 2和3兼容。(在这样的时刻,我希望能够提出编辑建议。)
贾斯珀

130

只需将其hello()放在函数下方,它将在您执行时执行python your_file.py

对于更整洁的解决方案,您可以使用以下方法:

if __name__ == '__main__':
    hello()

这样,仅当您运行文件时才执行该功能,而不是在导入文件时执行该功能。


3
如果要hello()接受命令行应提供的参数呢?
匿名的

2
在这种情况下,您可以发送sys.argv给该方法。或通过hello方法访问它
Wolph

3
此答案与import foo解决方案之间的区别是import foo允许在foo中调用任意函数而无需修改foo。
plafratt

是的,但是我不建议在测试目的之外使用该解决方案
Wolph '18

@Wolph嘿,使用这种结构,如何执行单独的功能(未包含在内hello())并从命令行运行它?
Souvik Ray

66

python -c 'from myfile import hello; hello()'这里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参数,我得到了不同的行为。
艾布拉姆(Abram)

29

我编写了一个快速的Python小脚本,可以从bash命令行调用它。它使用您要调用的模块,类和方法的名称以及您要传递的参数。我将其称为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\)

请注意最后一个转义括号以将元组作为Second方法的唯一参数传递的示例。

如果为该方法所需的参数传递的参数太少,则会出现错误。如果您通过太多,它将忽略额外费用。该模块必须在当前工作文件夹中,将PyRun放置在路径中的任何位置。


2
很好,但这并不是问题的答案。
弗朗西斯·科拉斯

14
我不敢苟同; 这正是问题所在。他问您如何从文件运行函数,而这正是这样做的。
Joseph Gagliardo 2015年

您能解释一下cmd_folder做什么的吗?
RyanDay '18

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

@MajorMajor我已经更新了答案,其中包括如何执行
Noam Hacker

在现场制作中这样做有什么危险吗?想要将其作为单元测试。
阿迪(Ardhi)

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 触发的模块,这也使得传递函数参数变得容易。它与一起安装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。火灾甚至有一种方式来调用一个函数不改变脚本:python -m fire file_name method_name。它还具有内置的argparser。
user3265569

6

有趣的是,如果目标是打印到命令行控制台或执行其他一些分钟的python操作,则可以将输入通过管道传递到python解释器中,如下所示:

echo print("hi:)") | python

以及管道文件

python < foo.py

*请注意,扩展名不必一定是.py才能正常工作。**还请注意,对于bash而言,您可能需要转义字符

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

考虑到带有hello()的foo.py示例,这就是上面的想法可以使用它的方式。 echo import foo;foo.hello() | python
阿林丹·罗伊休杜里

有什么方法可以通过此方法传递命令行参数?
sparkonhdfs 17-4-12

1
FWIW,以下是第三个示例的echo 'print("hi:)")' | python
较简洁的格式


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命令在命令行中输入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“导入Odd_Even_function; Odd_Even_function.OE(100)”的完整路径

选项2 exe \ python.exe -c“从Odd_Even_function import OE; OE(100)”的完整路径

谢谢。


0

此函数无法从命令行运行,因为它返回的值将不可用。您可以删除退货并改为使用打印


-2

使用python-c工具(pip install python-c),然后简单地编写:

$ python-c foo 'hello()'

或在python文件中没有函数名冲突的情况下:

$ python-c 'hello()'

-2

首先,您必须按照他们告诉您的方式调用该函数,否则该功能将在输出中不显示任何内容,之后保存文件并通过右键单击将文件的路径复制到文件的文件夹,然后单击“复制文件”转到终端并输入:-cd“文件的路径”-python“例如文件的名称(main.py)”,之后它将显示代码的输出。


-4

安装Spyder,让您的生活更轻松。打开文件,然后运行它(单击绿色箭头)。之后,您的hello()方法已定义并为IPython控制台所知,因此您可以从控制台中调用它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.