파이썬: 셸 스크립팅의 강력한 대안
파이썬은 또 다른 스크립팅 언어이며, 지금까지 살펴본 스크립팅 언어 중 가장 최신입니다. bash와 Perl과 유사하게 파이썬은 인터프리터 언어이며 shebang을 사용합니다. 셸 인터페이스는 없지만, REPL이라는 콘솔을 통해 파이썬 코드를 입력하여 시스템과 상호작용할 수 있습니다. 이 장에서는 다음과 같은 주제를 다룹니다:
- 파이썬이란 무엇인가?
- 파이썬 방식으로 Hello World 출력하기
- 파이썬 스타일의 인수 처리
- 중요한 공백(Indentation)
- 사용자 입력 읽기
- 파이썬으로 파일 쓰기
파이썬이란 무엇인가?
파이썬은 객체 지향 인터프리터 언어로, 사용하기 쉽고 빠른 애플리케이션 개발을 돕도록 설계되었습니다. 이는 언어에서 단순화된 의미론을 사용하여 달성됩니다.
파이썬은 1989년 말, 네덜란드 개발자 Guido van Rossum에 의해 창조되었습니다. 이 언어의 대부분은 명확함과 단순함을 목적으로 설계되었으며, 파이썬의 철학 중 하나는 다음과 같습니다:
"한 가지, 가능하다면 단 하나의 분명한 방법으로 문제를 해결해야 한다."
일반적으로 시스템에는 Python 2와 Python 3가 모두 설치되지만, 모든 최신 배포판은 Python 3로 전환하고 있습니다. 우리는 라즈베리 파이에 설치된 최신 버전인 Python 3를 사용할 것입니다.
셸은 없지만 REPL을 통해 파이썬과 상호작용할 수 있습니다: 읽기(Read), 평가(Evaluate), 출력(Print) 및 반복(Loop). 명령줄에서 `python3`를 입력하여 이에 접근할 수 있습니다. 다음과 유사한 화면이 나타나야 합니다:
우리는 `>>>` 프롬프트가 표시되는 것을 볼 수 있으며, 이를 REPL 콘솔이라고 합니다. 이는 bash와 Perl과 마찬가지로 스크립팅 언어임을 강조해야 합니다. 보통 생성된 텍스트 파일을 통해 코드를 실행합니다. 이 텍스트 파일은 일반적으로 `.py` 확장자를 가진 이름을 갖기를 원합니다.
REPL을 사용할 때 모듈을 가져와서 버전을 독립적으로 출력할 수 있습니다. Perl에서는 키워드를 사용하고, bash에서는 소스 명령을 사용하지만, 파이썬에서는 `import`를 사용합니다:
>>> import sys
모듈을 로드한 후에는 이제 버전을 출력하여 파이썬의 객체 지향 특성을 살펴볼 수 있습니다:
>>> sys.version
이 두 명령을 결합하면 다음과 유사한 출력이 나타날 것입니다:
파이썬을 설명하는 이 부분을 마무리하려면 파이썬의 철학을 살펴보겠습니다. REPL에서 `import this`를 입력할 수 있습니다:
이것은 단순히 파이썬의 철학 이상입니다. 실제로 모든 프로그래밍 언어에 대한 좋은 규칙이며 개발자를 위한 가이드라인이기도 합니다.
마지막으로 REPL을 종료하려면 Linux에서는 *Ctrl* + *d*, Windows에서는 *Ctrl* + *z*를 사용합니다.
파이썬 방식으로 Hello World 출력하기
우리가 파이썬으로 작성하는 코드는 명확하고 간결해야 하며, 덜 밀집된 것이 더 좋습니다. 첫 줄에 shebang을 사용한 다음 `print` 문을 사용해야 합니다. `print` 함수에는 줄 바꿈 문자가 포함되어 있으므로 행 끝에 세미콜론을 사용할 필요가 없습니다. 다음 예제에서 편집된 `$HOME/bin/hello.py` 버전을 볼 수 있습니다:
#!/usr/bin/python3
print("Hello World")
여전히 실행 권한을 추가해야 하지만, 이전처럼 `chmod`를 사용하여 코드를 실행할 수 있습니다. 다음 명령에 표시되지만, 이제는 이에 익숙해져야 합니다:
$ chmod u+x $HOME/bin/hello.py
마지막으로 이제 코드를 실행하여 인사말을 볼 수 있습니다.
다시 말하지만, 적어도 한 가지 언어를 아는 것은 다른 언어에 적응하는 것을 더 쉽게 만들며, 이는 많은 새로운 기능이 아닙니다.
파이썬 스타일의 인수 처리
지금까지 우리는 파이썬에 명령줄 인수를 전달하고 싶다는 것을 알아야 합니다. Perl과 유사하게 `argv` 배열을 사용하여 이를 달성할 수 있습니다. 하지만 bash와 더 유사하게, 파이썬을 사용할 때는 프로그램 이름을 다른 인수와 함께 배열에 조합합니다. 파이썬은 또한 대문자 대신 소문자를 사용하는 객체 이름을 사용합니다.
- `argv` 배열은 `sys` 객체의 일부입니다
- `sys.argv[0]`은 스크립트 이름입니다
- `sys.argv[1]`은 스크립트에 제공된 첫 번째 인수입니다
- `sys.argv[2]`는 두 번째로 제공된 인수이며, 이런 식으로 계속됩니다
- 인수 수항상 최소 1이므로, 제공된 인수를 확인할 때 이를 기억하십시오
인수 제공하기
만약 `$HOME/bin/args.py` 파일을 생성하면 작동 방식을 볼 수 있습니다. 파일은 다음과 같이 생성되어야 하고 실행 가능해야 합니다:
#!/usr/bin/python3
import sys
print("Hello " + sys.argv[1])
제공된 인수로 스크립트를 실행하면 다음 스크린샷과 유사한 내용이 나타날 것입니다:
우리의 코드는 여전히 매우 명확하고 간단합니다. 그러나 인수를 따옴표로 묶은 텍스트와 함께 `print` 문에 결합할 수 없다는 것을 이미 알아챘을 수 있습니다. 우리는 두 문자열을 연결하기 위해 `+` 기호를 사용합니다. 변수나 다른 유형의 객체를 나타내는 특정 기호가 없으므로, 정적 텍스트로서 따옴호 안에 나타날 수 없습니다.
인수 계산하기
이전에 언급했듯이, 스크립트 이름은 배열에서 인덱스 `0`인 첫 번째 인수입니다. 따라서 인수를 계산하려면 수항상 최소 1이어야 합니다. 다시 말해, 인수를 제공하지 않으면 인수 수는 1이 될 것입니다. 배열의 항목 수를 계산하려면 `len()` 함수를 사용할 수 있습니다. 스크립트에 새 줄을 포함하도록 편집하면 다음과 같이 작동하는 것을 볼 수 있습니다:
#!/usr/bin/python3
import sys
print("Hello " + sys.argv[1])
print(len(sys.argv))
코드를 실행하면 두 개의 인수를 제공한 것을 볼 수 있습니다. 스크립트 이름, 그 다음에는 문자열 `fred`입니다:
하나의 `print` 문을 사용하여 출력과 인수 수를 인쇄하려고 하면 파이썬이 데이터 형식을 혼합하는 것을 좋아하지 않습니다. 길이 값은 정수이며, 이는 변환 없이 문자열과 혼합할 수 없습니다. 다음 코드는 실패합니다:
#!/usr/bin/python3
import sys
print("Hello " + sys.argv[1] + " " + len(sys.argv))
하지만 이는 어려운 작업이 아니며, 명확한 변환만 필요합니다. 파이썬의 철학에서:
"명확성은 암시성보다 낫다."
수정된 코드는 다음과 같이 정상적으로 작동합니다:
#!/usr/bin/python3
import sys
print("Hello " + sys.argv[1] + " " + str(len(sys.argv)))
스크립트를 실행하고 인수를 제공하지 않으면 인덱스 `1`을 참조할 때 배열에 빈 값이 있을 것입니다. 이는 다음 스크린샷과 같이 오류를 유발할 것입니다:
물론 오류를 방지하기 위해 이 문제를 처리해야 하며, 이제 중요한 공백 부분으로 넘어갈 수 있습니다.
중요한 공백(Indentation)
파이썬과 대부분의 다른 언어 간의 주요 차이점 중 하나는 추가 공백이 특정 의미를 가질 수 있다는 것입니다. 코드의 들여쓰기 수준은 해당 코드 블록에 속함을 정의합니다. 지금까지는 생성된 코드를 행 시작 부분 이후로 들여쓰지 않았습니다. 이는 모든 코드가 동일한 들여쓰기 수준에 있고 동일한 코드 블록에 속함을 의미합니다. 우리는 중괄호나 `do` 및 `done` 키워드를 사용하는 대신 들여쓰기를 사용하여 코드 블록을 정의합니다. 네 개의 공백으로 들여쓰기를 사용한다면, 네 개의 공백을 사용해야 합니다. 이전 들여쓰기 수준으로 돌아가면 이전 코드 블록으로 돌아갑니다.
이는 복잡해 보일 수 있지만, 실제로는 매우 간단하며 코드를 명확하고 간결하게 유지할 수 있습니다. `arg.py` 파일을 편집하여 인수가 제공되지 않을 때 원치 않는 오류를 방지할 수 있습니다:
#!/usr/bin/python3
import sys
count = len(sys.argv)
if (count > 1):
print("Arguments supplied: " + str(count))
print("Hello " + sys.argv[1])
print("Exiting " + sys.argv[0])
`if` 문은 인수 수가 `1`보다 큰지 확인합니다. 이제 편의를 위해 인수 수를 `count`라는 자체 변수에 저장합니다. 코드 블록은 콜론으로 시작하며, 그 다음에 네 개의 공백으로 들여쓰기된 모든 후속 코드는 조건이 참일 때 실행될 코드의 일부입니다.
이전 들여쓰기 수준으로 돌아가면 메인 코드 블록으로 돌아가고 조건 상태에 관계없이 코드를 실행합니다.
다음 스크린샷에서 이를 볼 수 있으며, 인수를 사용하여 스크립트를 실행하고 인수 없이 실행할 수 있습니다:
사용자 입력 읽기
스크립트가 제공되는 인수에 관계없이 우리 이름으로 환영 메시지를 표시하고 싶다면, 스크립트 실행 시 데이터를 캡처하기 위한 프롬프트를 추가할 수 있습니다. 파이썬은 이를 간단하고 쉽게 구현할 수 있도록 합니다. 다음 스크린샷에 표시된 편집 파일에서 이를 구현하는 방법을 볼 수 있습니다:
우리는 스크립트에서 새 변수를 사용했으며, 처음에는 메인 블록에서 빈 문자열로 설정했습니다. 여기에 설정하면 이 변수가 전체 스크립트와 모든 코드 블록에서 사용 가능합니다.
파이썬 3에서는 `input` 함수를 사용할 수 있으며, 파이썬 2에서는 `raw_input`을 사용할 수 있습니다. 우리는 입력을 `name` 변수에 저장합니다. 인수를 제공하면 `else` 블록의 코드에서 가져오고 `name` 변수를 첫 번째로 제공된 인수로 설정합니다. 이는 메인 블록의 `print` 문에서 사용됩니다.
파이썬으로 파일 쓰기
이 장에 변화를 주기 위해, 이제 이 데이터를 파일에 인쇄하는 방법을 살펴보겠습니다. 다시 파이썬을 사용하여 이는 상당히 간단하고 쉽게 시작할 수 있는 방법입니다. 기존 `args.py`를 복사하겠습니다. 이를 `$HOME/bin/file.py`로 복사합니다. 새로운 `file.py`는 다음 스크린샷과 유사해야 하며 실행 권한이 설정되어야 합니다:
마지막 몇 줄만 수정한 것을 알 수 있습니다. 인쇄 대신 파일을 엽니다. 또한 파일의 인스턴스로 간주되기 때문에 파이썬의 더 많은 객체 지향 생활을 보았습니다. 파일을 열 때 추가 목적으로 엽니다. 이는 이미 내용이 있는 경우 기존 내용을 덮어쓰지 않음을 의미합니다. 파일이 존재하지 않으면 새 파일을 생성합니다. `w`를 사용하면 쓰기 위해 파일을 열게 되어 이는 덮어쓰기를 유발할 수 있으므로 주의해야 합니다.
이것이 간단한 작업임을 알 수 있습니다. 이것이 바로 파이썬이 많은 애플리케이션에서 사용되고 학교에서 널리 가르치는 이유입니다.