我有这段代码:
def hello():
return 'Hi :)'
我该如何直接从命令行运行此程序?
如果你的文件名为foo.py
,可以使用-c
(命令)参数:
$ python -c 'import foo; print foo.hello()'
或者,如果您不关心命名空间污染:
$ python -c 'from foo import *; print hello()'
还有一个折中方案:
$ python -c 'from foo import hello; print hello()'
$python -c "import foo;foo.hello()"
- Arindam Roychowdhuryprint foo.hello()
替换为print(foo.hello())
则可以。我没有足够的Python知识来解释这是为什么,如果有人能够解释一下可能发生了什么,那将不胜感激。 - Jasper只需要在函数下方添加hello()
,然后当你执行python your_file.py
时它就会被执行。
如果想要更简洁的解决方案,可以使用以下代码:
if __name__ == '__main__':
hello()
这样,只有在运行文件时才会执行该函数,而不是在导入文件时执行。
hello()
需要由命令行提供参数,该怎么办? - pretzlstylesys.argv
发送到该方法。或者从hello
方法中访问它。 - Wolphhello()
中)并从命令行运行它? - Souvik Raysys.argv
解析(例如使用 argparse
)来执行不同的方法。 - Wolph将此片段添加到您的脚本底部
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 Majorpython -c 'from 文件名 import hello; hello()'
这里需要将 文件名
替换为你的 Python 脚本的基本名称(例如,myfile.py
变成 myfile
)。
但是,如果 hello()
是您的 Python 脚本中的“永久”主入口点,则通常的方法如下:
def hello():
print "Hi :)"
if __name__ == "__main__":
hello()
这使你可以通过运行python myfile.py
或python -m myfile
来简单地执行脚本。
一些解释: __name__
是一个特殊的Python变量,它保存当前正在执行的模块的名称,除非该模块从命令行启动,在这种情况下它变成"__main__"
。
python -m foo -c 'foo.bar()'
和 python -c 'import foo; foo.bar()'
有什么区别?我发现它们的行为不同,似乎第一种情况下 -c 参数被忽略了。 - Abram-m mod:将库模块作为脚本运行(终止选项列表)
- bers我写了一个简短的 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 可以放在任何路径下。
我们可以这样写。我使用的是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
让我们简单点,只需使用一个模块...
尝试: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
python -m fire file_name method_name
。它还具有内置的argparser。 - user3265569有趣的是,如果目标是将内容打印到命令行控制台或执行其他小型Python操作,可以像这样将输入管道传递给Python解释器:
echo print("hi:)") | python
除了管道文件之外...
python < foo.py
echo print\(\"hi:\)\"\) | python
echo import foo;foo.hello() | python
- Arindam Roychowdhuryecho 'print("hi:)")' | python
- user3166580我有一个需求,需要在命令行上使用各种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
"""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
print "Hi :)"
而不是return 'Hi :)'
。 - Tamás