使用解析器命令设置函数

Setting a function with a parser command

当我启动我的代码时,我想选择一个将要使用的函数(从一组函数中)。不幸的是我有很多循环而且代码非常昂贵所以下面的伪代码是非常不推荐的:

import argparse
import mystuff


code body in which my_variable gets created

if args.my_index == 1:
  def my_func(my_variable):
    return my_variable + 1

if args.my_index == 2:
  def my_func(my_variable):
    return my_variable**2 +1

已使用以下命令:

$ python3 my_code.py --index 1

我正在考虑将该函数提升到 外部 class 模块,可能会使用 class 初始化的属性。

您可以在像元组这样的容器中注册您的函数。然后你可以通过索引检索它们。 ArgumentParser 对象的 .index 属性将比元组索引多 1:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--index', type=int)
args = parser.parse_args()

my_variable = 10
funcs = (lambda x: x + 1, lambda x: x ** 2 + 1, lambda x: x ** 3 + 1)

if args.index is not None:
    print(funcs[args.index - 1](my_variable))

这样当你使用 python3 my_code.py --index 1 执行脚本时,.index 是 1,所以你需要得到元组的第一项,即 args.index - 1.

输出:11

如果您的函数有任何机会遵循特定模式(如此处的 my_variable ** n + 1),您可以定义一个通用函数来处理它而无需注册所有函数:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--index', type=int)
args = parser.parse_args()

my_variable = 10

def func(x):
    return my_variable ** x + 1

if args.index is not None:
    print(func(args.index))

这是一个示例,您可以如何将基 class 与继承自它的 classes 函数一起使用,以自动构建命令行(使用基 __subclasses__() 方法 class) 并进行计算,而无需编写一些可笑的 if 语句序列。

有关 subclasses 的更多信息,请参阅 Python 文档中的 here

import argparse

# base class for all your functions to inherit from    
class mystuff():
        pass

# function classes inherit from mystuff, provide at least a docstring and a calculate() method.            
class fun1(mystuff):
    '''
    Calculate fun1
    '''
    def calculate(self,value):
        return value*2
    
class fun2(mystuff):
    '''
    Calculate fun2
    '''
    def calculate(self,value):
        return value*23

if __name__=="__main__":
    parser = argparse.ArgumentParser(description="Allow calling functions each defined in their own class")

    # find all the classes to be used as commandline arguments
    for fun in mystuff.__subclasses__():
#        print( f"Creating argument for {fun.__name__}" )
        parser.add_argument( f'--{fun.__name__}', default=0, dest='function', action='store_const', const=fun, help=fun.__doc__)
    parser.add_argument('variable', type=int, help="Value to pass to calculation")
    
    args = parser.parse_args()

    # create an instance and call its calculate function passing the variable value
    result = args.function().calculate(args.variable)
    
    print( f"Calling {args.function.__name__} with variable {args.variable} gives result {result}" )

    

获取用法:

fun1.py -h

给出:

usage: fun1.py [-h] [--fun1] [--fun2] variable

Allow calling functions each defined in their own class

positional arguments:
  variable    Value to pass to calculation

optional arguments:
  -h, --help  show this help message and exit
  --fun1      Calculate fun1
  --fun2      Calculate fun2

调用函数之一:

fun1.py --fun1 235

给出结果:

Calling fun1 with variable 235 gives result 470

我相信这可以做得更复杂,也许可以通过使用子解析器消除在每个函数名称前添加 -- 的需要。