如何将超过3个参数传递给getattr?

时间:2015-04-10 21:07:18

标签: python traceback

我正在学习如何使用python的*args***kwargs符号。我试图使用getattr将可变数量的参数传递给另一个文件中的函数。

以下代码将获取控制台输入,然后搜索包含放入控制台的函数的模块,然后使用参数执行该函数。

while True:
    print(">>>", end = " ")
    consoleInput = str(input())
    logging.info('Console input: {}'.format(consoleInput))
    commandList = consoleInput.split()
    command = commandList[0]
    print(commandList) # Debug print
    """Searches for command in imported modules, using the moduleDict dictionary,
    and the moduleCommands dictionary."""
    for key, value in moduleCommands.items():
        print(key, value)
        for commands in value:
            print(commands, value)
            if command == commands:
                args = commandList[0:]
                print(args) # Debug print
                print(getattr(moduleDict[key], command))
                func = getattr(moduleDict[key], command, *args)
                func()
                output = str(func)
    else:
        print("Command {} not found!".format(command))
        output = ("Command {} not found!".format(command))
    logging.info('Console output: {}'.format(output))

我尝试使用带参数的命令,例如我所做的自定义ping命令。但是,我得到了这个追溯:

Traceback (most recent call last):
  File "/home/dorian/Desktop/DEBPSH/DEBPSH.py", line 56, in <module>
    func = getattr(moduleDict[key], command, *args)
TypeError: getattr expected at most 3 arguments, got 4

如何将超过3个参数传递给getattr函数?

2 个答案:

答案 0 :(得分:4)

如果要将参数传递给函数,则需要在调用该函数中使用这些参数。 getattr()对您正在检索的属性一无所知,也不接受任何调用参数。

请改为:

func = getattr(moduleDict[key], command)
output = func(*args)

getattr()参数只接受对象,要从中检索的属性,以及可选的默认值(如果该属性不存在)。

请注意,您不需要在该功能上调用str();最好你可能希望将函数调用的返回值转换为string。

答案 1 :(得分:2)

要回答您提出的问题;你没有。 getattr只需要两个或三个参数。传递三个论点并不像你试图做的那样:

getattr(object, name[, default])

调用getattr(math, "sin")与编写math.sin相同。这将检索sin模块中名为math的属性,该属性恰好是一个函数。使用getattr执行此操作没有什么特别之处。如果您编写math.sin(i),则会从sin模块获取属性math并立即调用它。 getattr(math, "sin")(i)math.sin(i)基本相同。

由于函数调用的正常工作方式,您需要使用以下代码:

func = getattr(moduleDict[key], command)
func(*args[1:])

这将从您的模块获取命令功能,然后正常调用它,就像您直接调用模块中的函数一样。但这并不是代码中那部分唯一的错误。接下来,你写下这个:

output = str(func)

这也是错误的。 func不会被您调用的函数的返回值神奇地替换。如果它以这种方式工作,在您致电math.sin后,任何人都无法再次使用math.sin。存储在变量中的函数与任何其他函数一样,因此您显然会像任何其他函数一样检索其返回值:

func = getattr(moduleDict[key], command)
output = func(*args[1:])

除此之外,该段代码似乎有一个最后一个错误。 commandList[0:]什么也没做。您要求从第一个元素到最后一个元素的切片。所有这一切都是复制列表。你可能首先想要的是commandList[1:],除了命令之外,它会得到你的每个参数。解决这个问题,你得到:

args = commandList[1:]
func = getattr(moduleDict[key], command)
func(*args)