使用解析器命令设置函数

Posted

技术标签:

【中文标题】使用解析器命令设置函数【英文标题】:Setting a function with a parser command 【发布时间】:2022-01-08 00:48:40 【问题描述】:

当我启动我的代码时,我想选择一个将要使用的函数(从一组函数中)。不幸的是,我有很多循环并且代码非常昂贵,因此以下伪代码已被高度弃用:

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

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

【问题讨论】:

【参考方案1】:

您可以像元组一样在容器中注册您的函数。然后您可以通过索引检索它们。 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))

【讨论】:

lambda 函数是一种结构函数,因为您将指针指向“表达式”【参考方案2】:

这是一个示例,您可以如何使用带有函数的基类作为从它继承的类来自动构建命令行(使用基类上的 __subclasses__() 方法)并进行计算,而无需编写一些荒谬的 if 序列声明。

有关子类的更多信息,请参阅 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

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

【讨论】:

恕我直言,Sorus 提出的解决方案更简洁。无论如何,你的建议对我和其他许多人来说都是非常有教育意义的。

以上是关于使用解析器命令设置函数的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

在子解析器 args 之后添加*** argparse 参数

具有互斥必需参数的命令行解析器

如何为函数参数“*argv”添加解析器参数

Linux 命令解析器

Linux 命令解析器