如何通过getattr()动态方法调用返回值

时间:2017-09-13 08:39:41

标签: python-3.x return-value getattr dynamic-method hasattr

我有一个被调用的类,它运行一个while循环命令提示符,我使用dir()getattr()来动态创建命令shell的方法列表。我想返回值,但是从动态调用的方法返回只是退出到main while循环,为什么我该如何解决这个问题呢?

class myClass :
    def __init__(self) :
        self.commands = []
        for x in dir(self) :
                k = getattr( self, x )
                if hasattr(k, '__func__') :
                    self.commands.append(x)
            # strips off __init__ and __main__
            self.commands = self.commands[2:]

    def help(self, args=None) :
        for x in self.commands :

            ####
            #### The issue is here
            print('Command: {}'.format(x))
            f = getattr(self, x)('-h')
            desc = f()
            print('Description: {}'.format(desc))
        ...
        return SomeValue

    def cmd_b(self, args=None) :
        if args == '-h' :
            return 'Some description'
        ...
        return SomeValue

    def cmd_c(self, args=None) :
        ...
        return SomeValue

    def __main__(self) :
        while True :
            command = input(self.ENV['PS1'])
            command += ' '
            command = command.split()
            print(command)
            if len(command) > 1 :
                print(command)
                print(len(command))
                args = command[1:]
                command = command[0]
            else :
                command = command[0]
                args = None

            if command == 'exit'  :
                break

            if command not in dir(self) :
                print("Command `{}` not found".format(command))
                continue
            print(command)
            f = getattr( self, command )(args)
            x = f()

1 个答案:

答案 0 :(得分:0)

getattr并返回值

执行getattr(self, attr)时,会返回相应的对象,这与直接调用属性相同。 E.g:

class A:
    def __init__(self):
        self.v = 42
    def func(self):
        return "Remember your towel"

a = A()

以下是等效的

value = a.v
towel = a.func()

value = getattr(a, 'v')
towel = getattr(a, 'func')()

f = getattr(a, 'func')
towel = f()

两种情况下,变量valuetowels都是42"Remember your towel"

这应该回答你的问题。

但是:

代码中的主要问题

然而,代码中的主要问题与getattr无关。

help方法中,您引用了一个您从未定义的f函数,因此会引发异常。

但最大的问题是在__main__

的末尾
except:
    pass

最后。您应该从不这样做:您正在调整错误,使调试变得非常困难。

如果您希望使代码能够适应错误,您应该捕获所有错误并在某处报告,例如使用log messages

import logging

log = logging.getLogger()
# set up the logger

while:
    try:
        func()
    except Exception:
        log.exception('my nice message for the user')

如果你在代码中做了这样的事情,那么捕获像未定义的f函数这样的错误要容易得多。

一些建议:

  • help函数中,循环遍历包含的所有命令help,并打印其帮助。实现帮助的方式,这会导致无限递归。您应该跳过help函数中的help

  • 所有命令都返回None或字符串。当你按照上面的说明修改代码时,第63行会出现很多错误:f()

ps:如果您从python开始,请查看PEP8, the official python style guidelines