[python] invoke function with switch/case

역시 고민을 하면 할 수록 더 좋은 방법들이 나오네요. 아래 링크 2개의 조합 버전입니다.

[python] check command

[python] switch/case call function

def invoking(cmd) function입니다. invoke_command()를 recursive로 호출하면서 cmd의 validation을 체크하고 valid한 경우 mapping된 function을 호출합니다.

def invoking(cmd):
INVOKE_COMMAND = {
"There": {
"is": {
"a": {
"monster": command_monster, <-- function
"dragon": True <-- BooleanType
}
},
"are": {
"monsters": True,
"dragons": True,
}
},
"My": {
"name": {
"is": {
"monster": command_monster, <-- function
"dragon": command_dragon <-- function
}
}
}
}

return invoke_command(INVOKE_COMMAND, cmd, 0)

다음은 cmd가 valid할 경우 호출되는 함수입니다. 예를 들어서, cmd가 “There is a monster”이면 command_monster함수가 호출됩니다. “There is a dragon”을 호출하면 True를 return합니다.

def command_monster(cmd):
print('command_monster: {} function 실행'.format(cmd))
return True

def command_dragon(cmd):
print('command_dragon: {} function 실행'.format(cmd))
return True

def command_invalid(cmd):
print('invalid: {}'.format(cmd))
return True

다음 코드는 recursive함수입니다.

def invoke_command(allowed_command, command, index):
for key, v in allowed_command.items():
# print('k:{} / v:{}'.format(key, v))
if key == command[index]:
print('{} == {}'.format(key, command[index]))
index += 1
if isinstance(v, dict):
if len(command) <= index:
return None

return invoke_command(v, command, index)
elif isinstance(v, BooleanType):
print('-- BooleanType: {}'.format(v))
return v
elif callable(v):
print('-- callable: {}'.format(v.__name__))
return allowed_command.get(key, lambda x: command_invalid(x))(command)
else:
print('{} != {}'.format(key, command[index]))
continue
return
command_invalid(command)

실행 예제입니다.

“There is a monster” 실행 결과

cmd = "There is a monster".split(' ')
r = invoking(cmd)
print('result: {}'.format(r))
-- 실행 결과
There == There
is == is
a == a
monster == monster
-- callable: command_monster
command_monster: ['There', 'is', 'a', 'monster'] function 실행
result: True

“There is a dragon” 실행 결과

cmd = "There is a dragon".split(' ')
r = invoking(cmd)
print('result: {}'.format(r))
-- 실행 결과
There == There
is == is
a == a
monster != dragon
dragon == dragon
-- BooleanType: True
result: True

“My name is dragoooooon” 실행 결과(잘못된 command 실행)

cmd = "My name is dragoooooon".split(' ')
r = invoking(cmd)
print('result: {}'.format(r))
-- 실행 결과
There != My
My == My
name == name
is == is
monster != dragoooooon
dragon != dragoooooon
invalid: ['My', 'name', 'is', 'dragoooooon']
result: True

앞으로 기능 추가(command 추가) 될 것을 고려하여 조금 확장성 있게 만들기는 했는데… 딱 맘에 들지는 않네요^^;

Medium에 code snippet기능 좀 있었으면 좋겠네요.

Like what you read? Give Logan.81k a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.