【问题标题】:How to return value with dynamic method calls through getattr()如何通过 getattr() 使用动态方法调用返回值
【发布时间】:2017-09-13 08:39:41
【问题描述】:

我有一个运行 while 循环命令提示符的类,我正在使用 dir()getattr() 为命令 shell 动态创建方法列表。我想返回值,但是从动态调用的方法返回只是退出到主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()

【问题讨论】:

  • 你能修复缩进吗? __main__ 功能已关闭
  • 不是类的一部分 (myClass.__main__()),我并没有尝试发布整个代码,因为我已经发现我发布的内容可能不受欢迎。 @FrancescoMontesano
  • Francesco 说了什么。还看到def myClass :SyntaxError: invalid syntax。你可能想要def myClass(object):
  • 哎呀应该是 class myClass 如果我只是发布整个代码,它真的不会再长了,我想我添加的内容足以让它有意义 @jq170727
  • 是的,请更正您的代码。在 StackOverflow 上总是尽力发布MCVE - Minimal, Complete, and Verifiable example

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


【解决方案1】:

getattr 和返回值

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

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

【讨论】:

  • 好的,所以当我打电话给getattr(self, command) 时,它实际上是在那里被调用的。如果我在它前面加上 f = 然后 f 包含返回值,这是我找不到的以及为什么我调用未定义的 f(),因为在我的特殊情况下 str 不是可调用的,也不是 None值,我删除了尝试,除了并添加了if command == 'help' : continue 非常感谢您的帮助
  • 不客气。我建议您保留 try-except 块但记录错误。这样,即使出现错误(错误或错误调用的命令),您的 promtp 也会继续存在,但您不会丢失有关错误的信息
猜你喜欢
  • 2013-10-17
  • 2015-06-09
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 1970-01-01
相关资源
最近更新 更多