Development language/Python

Python-15. File-1 / 파일 입출력 / Open함수 / read메소드 / close메소드 / with구문

DOT-ICD 2022. 3. 18. 18:05
728x90

Q. 파일 입출력?

 파일 입출력의 경우, 프로그램에서 매우 중요한 부분을 차지하기 때문에, 잘 알고있어야 하는 부분이다.

 

 말 그대로, 파일을 읽고 쓰는 과정에 관련된 것을 의미한다. 프로그램의 작동과정에서 어떤 데이터를 불러와야 하는 경우도 있고, 만들어낸 데이터를 특정한 파일에 저장해야하는 경우도 있다. 이러한 기능을 Python을 통해 어떻게 구현할 수 있는지 알아보자.

 

※파일 입출력의 경우, 언어에 따라 그 방식이 꽤 상이한 경우가 많다. 이 포스트에서는 Python을 통한 입출력만을 다룬다.


파일의 종류

 우리가 파일이라고 일컫는 데이터들은 그 형태가 매우 다양하다. 예를 들어, 가장 간단한 형태라고 할 수 있는 텍스트 파일부터, 음악, 비디오, 엑셀 등등 여러가지 응용프로그램에서 작성하는 파일의 형태가 매우 다양하게 존재한다. 

 

 가장 간단한 형태인 텍스트 파일의 경우, 그 파일을 이루는 데이터는 오로지 문자들로 이루어진 내용물만 존재한다.

그러나, 다른 형태의 파일인 경우, 그 파일의 형태(포맷)에 대한 정보를 표현하고자 하는 데이터와 함께 저장한다. (이는 엑셀과 같은 파일에 아무것도 작성하지 않은채로 저장했을 때, 그 파일의 용량을 확인해보면 알 수 있다. 텍스트 파일을 제외한 그 어떤 파일도 어떤 데이터를 포함하지 않았을 때 그 용량이 0byte인 경우는 없다!)

 

 따라서, 특정 포맷은 특정 응용프로그램에서만 온전하게 열어 그 안의 내용물을 확인할 수 있는 것이다. (ppt파일을 메모장에서 열 수는 없다!)


 텍스트 파일이 가장 기초적인 파일이고, 읽고 쓰는 것에 있어서 상대적으로 자유로우므로, 텍스트 파일을 통해 파일 입출력에 대해 알아보자.


Text File

 우선, 텍스트 파일은 위에 언급된 특징으로 인해 가장 적은 디스크 공간을 차지하고, 처리하기 쉬우며, 오로지 문자만을 저장할 수 있다. 파일의 확장자로 .txt를 사용한다. 


.py

 파이썬 파일의 기본 저장 파일인 .py파일 역시 텍스트 파일의 일종이다. (.py파일을 메모장으로 열 수 있다!)

단지, 특정한 문법이 지켜진 텍스트 파일을 의미하는 것이다. (들여쓰기 등)

 

 파이썬 인터프리터는 .py확장자를 가진 텍스트 파일을 읽을 수 있는 기능을 가진 프로그램이고, 그 파일을 읽어 프로그램으로 실행하는 일종의 프로그램이다. (상자 안의 상자 안의 상자 같은 느낌...!)


Python을 통해 파일 열기


Example

처음 해본다면 꽤 헷갈릴 수 있기 때문에, 예시와 함께 알아보자.

1. 경로(directory) 만들기

 윈도우 상에서 경로를 만드는 것은 너무나도 간단하다. (리눅스 등의 운영체제에서 경로를 만드는 것은 추가로 작성예정) 위와 같이, 내가 원하는 위치에 폴더를 만들면 경로를 만들어낸 것이다!

 

 이제 이 위치에 텍스트 파일을 작성하여 저장하고, .py파일을 코딩하여 저장한 뒤 실행시키면 된다!

 

2. 메모장을 사용하여 텍스트 파일 작성

 이와 같이 윈도우 메모장(note pad)(다른 운영체제의 경우 해당 운영체제에 존재하는 텍스트 편집기를 사용하자)에 위와 같이 텍스트를 작성하자. 

 

3. 작성한 텍스트 파일을 만들어둔 경로에 저장

 이와 같이, 1의 단계에서 생성한 경로에 텍스트 파일을 저장해주자! 이때, 텍스트 파일의 이름을 통해 파이썬 프로그램에서 파일을 불러와야 하므로, 이름을 잘 기억해두자!

 

4. 파일을 여는 프로그램을 파이썬을 통해 .py형식으로 작성 후, 3의 단계에서 텍스트 파일을 저장한 경로에 저장.

 파이썬 코드에서 파일을 열기 위해선 당연하게도 파일을 여는 함수가 필요하다!

 미리 빌트인된 함수 중 open 함수를 사용해보자.

file = open('Sample text.txt','r')
contents = file.read()
print(contents)
file.close()

  위와 같은 코드를 작성해서, .py파일로 3의 경로와 같은 경로에 저장해주자.

 이후, 작성된 .py파일을 실행시켜보자. 실행시키는 것은 간단하다. 에디터 창을 끄지 말고 그대로 실행시키면 된다. 

 잘 진행됐다면, 위와 같은 결과를 확인할 수 있다.


 이제 어떻게 위와 같은 과정을 통해 파일을 불러오는지 한줄한줄 코드를 뜯어보며 알아보자.

첫번째 줄

 첫번째 코드는 간단하다. open 함수를 사용하여 파일을 불러와 file객체에 저장하게 된다.

file = open('Sample text.txt','r')

Open()

 open 함수의 매개변수를 보면, 첫번째 매개변수로 파일의 이름을 입력받고, 두번째 매개변수로 파일을 어떤 목적으로 여는지에 대한 변수를 입력받는다. 이때, 두번째 매개변수로 입력된 'r' 즉 문자 r은 읽기모드로 파일을 불러옴을 의미한다.

 읽기모드로 불러온 파일에 대해서는 수정이 불가하며, 오로지 파일의 내용을 읽어오는 것만을 수행할 수 있다.


두번째 줄

contents = file.read()

 첫번째 줄에서 우리는 Sample text 파일에 대한 객체를 open 함수를 통해 생성하였다. 우리가 이 객체 안에 담긴 내용을 사용하기 위해서는 위 과정을 통해 생성된 객체의 read()메소드를 사용해야 한다.

 

 *여기서 "굳이 한번으로 끝날 일을 왜 두번에 나누어서 하는거지?"라는 혼란이 생길 수 있다. 이는 open함수를 통해 생성된 객체에 대한 이해를 통해 해결할 수 있다. open함수를 통해 생성된 객체는 파일 커서의 위치에 대한 정보만을 담고 있다고 생각해볼 수 있다. 워드 프로세서를 사용할 때, 우리는 깜빡이는 커서를 통해 내가 어디쯤에 글을 쓰고 있는지, 또는 어디쯤에 글을 읽고 있는지 알 수 있다. 이를 그대로 적용해보면, open함수를 통해 파일을 열게 될 때, 그 반환값인 객체는 해당 파일에서의 파일 커서라고 생각할 수 있다. 우리가 파일을 읽을 때, 파일커서를 한칸씩 움직이며 내용을 읽어내려가듯, open함수를 통해 생성된 객체 역시 그러한 파일 커서의 움직임을 재현하는 객체라고 생각할 수 있다. 아래의 read메소드에 대해 알아보며 더 자세히 알아보도록 하자.

 

 


read()

 이 메소드는 open함수로 생성된 객체가 가지는 파일 속의 내용을 텍스트의 형태로 가져와 반환하는 함수이다. 

따라서, 두번째 줄의 코드에서 file.read()라는 형태로 객체의 메소드를 사용하였고, 그 결과로 반환된 텍스트 즉 파일 속의 내용을 contents라는 객체에 문자열의 형태로 다시 담아주게 되는 것이다.

 

 이를 통해 알 수 있는 점은, 우리는 open함수를 통해 얻게 된 객체를 통해 불러온 파일의 내용을 바로 알아볼 수는 없음을 의미한다. (open을 통해 얻게 된 객체는 파일의 내용이 아니라, 파일을 읽고 쓸 수 있는 커서를 가져온 것과 같은 것이기 때문에..!) 우리는 이 커서의 행동 즉 메소드를 통해 파일이 가지고 있는 내용을 읽거나 쓸 수 있다. read메소드는 이러한 관점에서, 커서가 파일을 읽는 행동을 수행하는 메소드라고 이해할 수 있다. 

 

 주의할 점은, 이 파일을 읽어내는 커서는 왼쪽에서 오른쪽으로, 위에서 아래로의 방향으로만 움직인다는 것이다! 즉, 파일을 읽다가 내가 원하는 지점으로 으로 돌아가서 다시 읽는 등의 동작을 수행할 수 없다! 또, 커서가 몇칸의 내용물을 읽을지에 대해서 매개변수로 넘겨줄 수 있다. 이때, 이 커서의 위치는 read메소드를 수행한 뒤 초기화되지 않는다. 아래의 예제를 보자.

file = open('Sample text.txt','r')

contents1 = file.read(12)
contents2 = file.read()

print(contents1)
print(contents2)

file.close()

실행결과

 위의 예시에서 알 수 있듯, read메소드에 매개변수로 숫자를 입력하게 되면, 해당 숫자만큼의 개수만큼 파일커서를 이동시키며 내용물을 읽어내고, 매개변수가 존재하지 않는다면, 파일의 끝까지 내용물을 읽어내게 된다.

 물론, 의도적으로 파일을 끝까지 읽지 않고 4번째 줄의 close메소드를 사용할 수 있다. 이에 대해서는 해당 문단에서 다시한번 알아보자. 


세번째 줄

print(contents)

 contents에 저장된 문자열을 출력. 이때, contents에 저장된 문자열은 두번째 줄에서 알아보았듯 불러온 파일의 내용물이다.

 


네번째 줄

 

file.close()

 open함수로 생성된 객체를 오류없이 닫아주는 close() 메소드를 사용한다.

 


close()

 이 메소드의 경우, 위의 설명 그대로, open함수로 생성된 객체를 제거하는 역할을 한다. 이후 다시 파일을 open함으로써, 위에서 언급했던 read()메소드를 사용한 후의 커서 위치를 초기화시켜줄 수 있다. 

 또한, 파일을 open했다면 반드시 close해주어야 한다. 이후에 파일이 다시 사용될 때 의도치 않은 커서위치로 인해 오류가 발생하는 것을 막는 등의 이유로 인해 습관을 들여야 한다.

 

 그러나 매번 이러한 방식으로 파일을 읽고 쓰는 것은 어찌보면 상당히 귀찮은 일일 수 있다. 따라서, 이를 해결하기 위해 파이썬에서는 with구문을 사용할 수 있다.

 


with Statement

with 구문은 명시하지 않아도, open을 통해 생성된 객체의 close메소드를 사용하게 해주는 구문이라고 생각하면 된다.

사용방법은 아래와 같다.

with open('Sample text.txt','r') as file:
    contents = file.read()

print(contents)

실행결과

close메소드를 명시해 사용한 이전의 예시와 실행결과가 일치함을 알 수 있다.


이 의미를 다시 생각해보면, open()함수로 파일을 불러와 객체를 생성한다는 것은 우리가 우리가 윈도우 상에서 더블클릭을 통해 어떤 파일을 여는 것과 같은 행동이라고 할 수 있다. 

728x90