ChatGPT解决这个技术问题 Extra ChatGPT

从命令行运行函数

我有这个代码:

def hello():
    return 'Hi :)'

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

可能您的意思是 print "Hi :)" 而不是 return 'Hi :)'

F
Frédéric Hamidi

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

我注意到在 Windows shell 上,您需要双引号而不是单引号。 $python -c "import foo;foo.hello()"
如果文件不在本地目录或 PYTHONPATH 上怎么办?
出于某种原因,这对我不起作用,而将 print foo.hello() 替换为 print(foo.hello()) 可以。我没有 python 知识来解释为什么会这样,所以如果其他人可以解释可能发生的事情,那将不胜感激
@Jasper,您必须使用 python 3,它需要 print 函数才能将其参数放在括号中
虽然这个答案是十年前写的,但它是今天谷歌的顶级结果。我相信这就是这个网站的目的:一个寻找相关答案的地方,而不是不断发展的语言的证明。常见问题解答实际上提到使帖子保持最新是进行编辑的重要原因。我想说在这个答案中添加一个关于 python 版本的部分将是一种更好的方式来体现语言的变化,但我认为将代码更改为跨版本兼容是一个更优雅的解决方案。编辑历史将永远证明过去是什么。
W
Wolph

只需将 hello() 放在函数下方的某个位置,它就会在您执行 python your_file.py 时执行

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

if __name__ == '__main__':
    hello()

这样该函数只会在您运行文件时执行,而不是在您导入文件时执行。


如果 hello() 采用应该由命令行提供的参数怎么办?
在这种情况下,您可以将 sys.argv 发送到该方法。或者从 hello 方法访问它
这个答案和 import foo 解决方案之间的一个区别是 import foo 允许在 foo 中调用任意函数而不修改 foo。
这是真的,但我不会推荐超出测试目的的解决方案
@Wolph 嘿,有了这个结构,我如何执行一个单独的函数(不包含在 hello() 中)并从命令行运行它?
T
Tamás

python -c 'from myfile import hello; hello()' 其中 myfile 必须替换为 Python 脚本的基本名称。 (例如,myfile.py 变为 myfile)。

但是,如果 hello() 是 Python 脚本中的“永久”主入口点,那么执行此操作的常用方法如下:

def hello():
    print "Hi :)"

if __name__ == "__main__":
    hello()

这使您只需运行 python myfile.pypython -m myfile 即可执行脚本。

这里有一些解释:__name__ 是一个特殊的 Python 变量,它保存当前正在执行的模块的名称,except 当模块从命令行启动时,在这种情况下它变为 "__main__"


python -m foo -c 'foo.bar()'python -c 'import foo; foo.bar()' 有什么区别?我得到不同的行为,在第一种情况下似乎忽略了 -c 参数。
P
Pikamander2

将此代码段添加到脚本的底部

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 我已经更新了答案,包括如何做到这一点
在现场制作中这样做有什么危险吗?就像想把它作为一个单元测试。
D. Jagatiya's answer 有一个更完整的传递参数示例——它将所有参数传递给函数,如果用户没有传递正确数量的参数,你会得到一个合理的错误。
@Ardhi:我不会在 prod 中这样做,因为它允许调用文件中的任何全局函数,这使得它变得脆弱。使用 pytest for easy testing setup
J
Joseph Gagliardo

我编写了一个可以从 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\)

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

如果您传递的参数太少而无法满足该方法的需要,则会出现错误。如果你传递太多,它会忽略额外的。模块必须在当前工作文件夹中,PyRun 可以在路径中的任何位置。


这很好,但这并不是问题的真正答案。
我不敢苟同;这正是问题所在。他问你如何从文件中运行一个函数,而这正是它的作用。
你能解释一下 cmd_folder 的作用吗?
D
D. Jagatiya

我们可以这样写。我用过 python-3.7.x

import sys

def print_fn():
    print("Hi")

def sum_fn(a, b):
    print(a + b)

if __name__ == "__main__":
    args = sys.argv
    # args[0] = current file
    # args[1] = function name
    # args[2:] = function args : (*unpacked)
    globals()[args[1]](*args[2:])

python demo.py print_fn
python demo.py sum_fn 5 8

C
Charles Clayton

让我们自己简化一点,只使用一个模块......

尝试: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 中有一个 bug,但在 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。
T
Torie J

有趣的是,如果目标是打印到命令行控制台或执行一些其他微小的 python 操作,您可以像这样将输入管道输入到 python 解释器中:

echo print("hi:)") | python

以及管道文件..

python < foo.py

*请注意,扩展名不必是 .py 才能使第二个工作。 **另请注意,对于 bash,您可能需要转义字符

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

考虑带有 hello() 的 foo.py 示例,这就是如何使用上面的想法。 echo import foo;foo.hello() | python
有没有办法用这种方法传入命令行参数?
FWIW,对于第三个示例,以下内容稍微干净一些:echo 'print("hi:)")' | python
v
vascop

如果您使用 pip install runp 安装 runp 软件包,则需要运行:

runp myfile.py hello

您可以在以下位置找到存储库:https://github.com/vascop/runp


项目与 Python 3 不兼容。
i
iLoveTux

我需要在命令行上使用各种 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

A
Al Conrad

像这样的东西: 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

A
Alper Kucukkomurler

下面是包含函数定义的 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)" 的完整路径

谢谢。


E
Eric Duminil

此脚本与此处的其他答案类似,但它还列出了可用的函数,以及参数和文档字符串:

"""Small script to allow functions to be called from the command line.
Run this script without argument to list the available functions:

    $ python many_functions.py
    Available functions in many_functions.py:

    python many_functions.py a  : Do some stuff

    python many_functions.py b  : Do another stuff

    python many_functions.py c x y : Calculate x + y

    python many_functions.py d  : ?

Run this script with arguments to try to call the corresponding function:

    $ python many_functions.py a
    Function a

    $ python many_functions.py c 3 5
    3 + 5 = 8

    $ python many_functions.py z
    Function z not found
"""

import sys
import inspect

#######################################################################
#                         Your functions here                         #
#######################################################################

def a():
    """Do some stuff"""
    print("Function a")

def b():
    """Do another stuff"""
    a()
    print("Function b")

def c(x, y):
    """Calculate x + y"""
    print(f"{x} + {y} = {int(x) + int(y)}")

def d():
    # No doc
    print("Function d")

#######################################################################
#         Some logic to find and display available functions          #
#######################################################################

def _get_local_functions():
    local_functions = {}
    for name, obj in inspect.getmembers(sys.modules[__name__]):
        if inspect.isfunction(obj) and not name.startswith('_') and obj.__module__ == __name__:
            local_functions[name] = obj
    return local_functions

def _list_functions(script_name):
    print(f"Available functions in {script_name}:")
    for name, f in _get_local_functions().items():
        print()
        arguments = inspect.signature(f).parameters
        print(f"python {script_name} {name} {' '.join(arguments)} : {f.__doc__ or '?'}")


if __name__ == '__main__':
    script_name, *args = sys.argv
    if args:
        functions = _get_local_functions()
        function_name = args.pop(0)
        if function_name in functions:
            function = functions[function_name]
            function(*args)
        else:
            print(f"Function {function_name} not found")
            _list_functions(script_name)
    else:
        _list_functions(script_name)

不带参数运行此脚本以列出可用函数:

$ python many_functions.py
Available functions in many_functions.py:

python many_functions.py a  : Do some stuff

python many_functions.py b  : Do another stuff

python many_functions.py c x y : Calculate x + y

python many_functions.py d  : ?

使用参数运行此脚本以尝试调用相应的函数:

$ python many_functions.py a
Function a

$ python many_functions.py c 3 5
3 + 5 = 8

$ python many_functions.py z
Function z not found

u
user2495144

使用命令 python 在命令行中输入 python 始终是一个选项

然后导入你的文件,所以导入 example_file

然后使用 example_file.hello() 运行命令

这避免了每次运行 python -c 等时出现的奇怪的 .pyc 复制功能。

可能不如单个命令方便,但可以快速修复从命令行输入文件的文本,并允许您使用 python 调用和执行文件。


S
Shubham

此函数无法从命令行运行,因为它返回的值将不会被处理。您可以删除退货并改用 print


j
jadn

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

$ python-c foo 'hello()'

或者如果您的 python 文件中没有函数名冲突:

$ python-c 'hello()'

S
ShahadM

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


I
Ivana

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