Python의 cmd 모듈에는 Cmd라는 단 하나의 클래스만 포함되어 있습니다. 이 클래스는 사용자가 직접 정의하는 라인 지향(line-oriented) 명령줄 인터프리터 프레임워크의 기반 클래스(base class)로 활용됩니다.
Cmd 클래스란?
Cmd 클래스 또는 이를 상속한 서브클래스의 객체는 라인 지향 인터프리터 프레임워크를 제공합니다. 서브클래스가 상속받아 사용할 수 있는 주요 메서드는 다음과 같습니다.
cmdloop() 메서드
cmdloop() 메서드는 객체를 무한 루프에 진입시키고, 사용자 입력을 받아 해당 입력에 알맞은 명령 처리 메서드로 전달하는 역할을 합니다.
루프가 시작되면 cmdloop() 메서드에 매개변수로 전달한 안내 메시지가 화면에 표시되며, 기본 프롬프트인 (cmd)는 객체의 prompt 속성을 통해 자유롭게 변경할 수 있습니다.
명령 입력의 해석 방식
인터프리터 객체는 사용자 입력을 두 부분으로 나누어 해석합니다.
- 첫 번째 부분: 앞에
do_가 붙은 형태로 클래스 내부의 메서드 이름으로 취급됩니다. - 두 번째 부분: 해당 메서드에 전달되는 매개변수로 처리됩니다.
예를 들어 사용자가 hello Python이라고 입력하면, 인터프리터는 클래스 안에서 do_hello() 메서드를 찾아 'Python'을 인자로 넘겨 실행하려고 시도합니다. 만약 해당 메서드가 정의되어 있지 않다면 오류 메시지가 출력됩니다.
help 기능 활용하기
Cmd의 서브클래스는 do_help() 메서드를 기본으로 상속받습니다. 사용자가 help hello처럼 입력하면 hello 관련 메서드의 docstring(문서화 문자열)을 도움말 텍스트로 보여주며, 만약 help_hello() 메서드가 별도로 정의되어 있다면 그 메서드가 대신 실행됩니다.
실전 예제: 사칙연산 인터프리터
다음 예제는 라인 지향 인터프리터 프레임워크의 실제 적용 사례를 보여줍니다. 코드는 먼저 cmd 모듈을 임포트하고 Cmd 클래스를 상속하는 서브클래스를 정의합니다.
MathOps 클래스는 add, sub, mul, div 네 가지 메서드(모두 do_ 접두사 사용)를 docstring과 함께 정의합니다.
MathOps 객체를 생성하고 cmdloop() 메서드를 호출하여 루프를 시작합니다. 프롬프트 앞에서 help를 입력하면 정의된 모든 메서드 이름이 목록으로 표시됩니다. 특정 메서드 이름과 함께 help를 입력하면 해당 메서드의 docstring이 출력됩니다. 메서드를 호출하려면 메서드 이름과 필요한 인자를 입력한 후 Enter 키를 누르면 됩니다. 실행 결과가 화면에 표시되고 프롬프트가 다시 나타나며, Ctrl+D(EOF)를 입력해 루프를 종료할 때까지 이 과정이 반복됩니다.
from cmd import Cmd
class MathOps(Cmd):
def do_add(self, args):
'''add two numbers'''
num=args.split()
print ('addition:',int(num[0])+int(num[1]))
def do_sub(self, args):
'''subtract two numbers'''
num=args.split()
print ('subtraction:',int(num[0])-int(num[1]))
def do_mul(self, args):
'''multiply two numbers'''
num=args.split()
print ('multiplication:',int(num[0])*int(num[1]))
def do_div(self, args):
'''perform division'''
num=args.split()
print ('division:',int(num[0])/int(num[1]))
def do_EOF(self, args):
return True
op=MathOps()
op.prompt= "->"
op.cmdloop("loop starts. Press ^D to exit")
실행 결과 예시
위 스크립트를 실행했을 때의 샘플 출력은 아래와 같습니다.
loop starts. Press ^D to exit ->help Documented commands (type help ): ======================================== add div help mul sub Undocumented commands: ====================== EOF ->help add add two numbers ->add 5 7 addition: 12 ->div 10 5 division: 2.0 -> >>>