Как вернуть значение с помощью динамических вызовов методов через getattr()
У меня есть класс, который называется, который запускает командную строку цикла while, я использую dir()
а также getattr()
динамически создавать список методов для командной оболочки. Я хочу вернуть значения, но возвращение из динамически вызываемого метода просто завершает основной цикл 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 ответ
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()
переменные value
а также towels
являются 42
а также "Remember your towel"
в обоих случаях.
Это должно ответить на ваши вопросы.
ТЕМ НЕ МЕНИЕ:
Основная проблема в коде
Однако основная проблема в коде не имеет ничего общего с getattr
,
в help
метод, который вы ссылаетесь на f
функция, которую вы никогда не определяете, так что возникает исключение.
Но большая проблема в конце __main__
:
except:
pass
в конце. Вы никогда не должны делать это: вы заставляете ошибки замолчать, что затрудняет их отладку.
Если вы хотите сделать свой код устойчивым к ошибкам, вы должны перехватить все ошибки и сообщить о них где-нибудь, например, используя сообщения журнала:
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, официальные рекомендации по стилю Python