如何通过 getattr() 使用动态方法调用 return 值
How to return value with dynamic method calls through getattr()
我有一个调用的 class 运行 while 循环命令提示符,我正在使用 dir()
和 getattr()
动态创建命令的方法列表 shell。我想要 return 值,但是动态调用方法中的 return 只是退出到主 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()
getattr
和 return 值
当您执行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()
变量value
和towels
在这两种情况下都是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
。
所有命令return None
或一个字符串。当您按照上面的指示修复代码时,您会从第 63 行得到很多错误:f()
ps:如果你是从python开始的,看看PEP8, the official python style guidelines
我有一个调用的 class 运行 while 循环命令提示符,我正在使用 dir()
和 getattr()
动态创建命令的方法列表 shell。我想要 return 值,但是动态调用方法中的 return 只是退出到主 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()
getattr
和 return 值
当您执行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()
变量value
和towels
在这两种情况下都是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
。所有命令return
None
或一个字符串。当您按照上面的指示修复代码时,您会从第 63 行得到很多错误:f()
ps:如果你是从python开始的,看看PEP8, the official python style guidelines