파이썬 - 파일, 객체 지향, 예외

‎육란·2023년 9월 24일

파이썬 알고리즘

목록 보기
4/8


오늘도 파이썬 알고리즘 공부에 앞서 파이썬 기본 문법을 살펴보겠다.

오늘 살펴볼 파이썬 기본 문법은 파일, 객체지향, 예외이다.

이전과 같이 https://wikidocs.net/85 를 참고하였다.



6. 파일


6.1 텍스트 파일


파이썬에서 텍스트 파일을 다룰 수 있다.

  • 파이썬으로 텍스트 파일(txt)을 읽는 방법을 알아보겠다.

open() 함수로 텍스트 파일을 받아오고
read() 함수로 텍스트 파일을 읽을 수 있다.

>>> f = open('C:\\python_newbie\\Python_for_Fun.txt')
>>> test = f.read()
>>> print(test)

이 때 받아온 파일의 줄 바꿈은 자동으로 '\n' 이 생겨있다.

파일을 닫아주면 좋지만, 파일을 잊고 닫지 않더라도 파이썬에서 자동으로 닫아준다.


  • 텍스트 파일에 글을 쓰려면 open()을 한 후에 write() 함수를 사용한다.
>>> letter = open('C:\\python_newbie\\letter.txt', 'w') # 새 파일 열기
>>> letter.write('Dear Father,')                      # 아버님 전상서
>>> letter.close()                                    # 닫기

자세히 보면 파일명 뒤에 w라고 써주었다.
아까 파일의 데이터를 읽기만 할 때와 달리, 파일에 데이터를 쓰려고 할 때는 미리 '파일에 데이터를 쓰겠다'는 사실을 알려줄 필요가 있기 때문이다.

close() 함수로 파일을 닫아주지 않으면 txt파일에 데이터가 추가되지 않으니 꼭 닫아주어야 한다.

파일에 데이터가 원래 들어있는데 w 모드로 파일을 열면 원래 있던 데이터가 없어져버린다.
파일에 들어있는 데이터를 지우지 않고 내용을 추가하려면 a+ 모드를 지정해줘야 한다.

>>> letter = open('C:\\python_newbie\\letter.txt', 'a+')
>>> letter.write('\n\nHow are you?')
>>> letter.close()


6.2 한 줄씩 다루기


파일을 처음부터 끝까지 읽을 땐 read() 함수를 사용하였다.
한 줄씩 읽을 때는 readline() 을 사용한다.

>>> f.readline()
'A. HISTORY OF THE SOFTWARE\n'

파일을 쭉 읽다가 \n을 만나면 멈추게 되는 것이다.

이를 활용하여 반복문을 이용해 원하는 줄 수만큼만 읽어들일 수 있다.

readline() 함수 대신 readlines() 함수를 사용하면 한 줄, 한 줄이 각각 리스트의 원소로 들어간다.

>>> f = open('LICENSE.txt')
>>> lines = f.readlines()
>>> lines[:2]
['A. HISTORY OF THE SOFTWARE\n', '==========================\n']

6.3 파일을 입맛대로


pickle

pickle 모듈은 조금 복잡한 자료를 파일에 읽고 쓸 때 사용한다.
파이썬에서 만들어지는 것은 뭐든지 다 파일에 적을 수 있다.

>>> users = {'kim':'3kid9', 'sun80':'393948', 'ljm':'py90390'}
>>> f = open('users', 'wb')
>>> import pickle
>>> pickle.dump(users, f)
>>> f.close()

dump는 users 리스트를 파일 f에 기록한다.
open 뒤에 있는 wb 는 파일을 일반 텍스트가 아닌 바이트 형식으로 쓰겠다는 뜻이다.

이렇게 하면 파이썬이 실행되는 경로에 users 파일이 만들어진 것을 볼 수 있다.

os.path.exists()로도 확인할 수도 있다.

>>> import os
>>> os.path.exists('users')
True

파일 내용을 파이썬에서 읽어보여면 pickle 모듈의 load() 함수를 사용한다.

>>> f = open('users', 'rb')
>>> a = pickle.load(f)
>>> print(a)
{'sun80': '393948', 'kim': '3kid9', 'ljm': 'py90390'}

glob

glob는 파일들의 리스트를 뽑을 때 사용하는데, 파일의 경로명을 이용해서 입맛대로 요리할 수 있다.

>>> from glob import glob
>>> glob('*.exe')               # 현재 디렉터리의 .exe 파일
['python.exe', 'pythonw.exe']
>>> glob('*.txt')               # 현재 디렉터리의 .txt 파일
['LICENSE.txt', 'NEWS.txt']

glob() 함수는 인자로 받은 패턴과 이름이 일치하는 모든 파일과 디렉터리의 리스트를 반환한다. 패턴을 그냥 *라고 주면 모든 파일과 디렉터리를 볼 수 있다.


os.path

glpb와 함께 os.path 모듈을 사용해보자.

from glob import glob
from os.path import isdir

for x in glob('*'):
    if isdir(x):                # 디렉터리인가?
        print(x, '<DIR>')
    else:
        print(x)

glob(*) 을 사용해 얻은 리스트의 원소 x를 하나씩 출력하되, 그것이 디렉터리이면 <DIR>이라는 문자열을 뒤에 붙여서 출력하게 한다.

실행 결과는 다음과 같다.

DLLs <DIR>
Doc <DIR>
img_read.py
include <DIR>
Lib <DIR>
libs <DIR>
LICENSE.txt
NEWS.txt
python.exe
python3.dll
python38.dll
pythonw.exe
Scripts <DIR>
tcl <DIR>
Tools <DIR>
vcruntime140.dll


7. 객체 지향


7.1 클래스와 인스턴스


객체 지향의 개념은 자바를 통해 많이 공부했으므로 기본적인 설명은 넘어가겠다.

클래스를 만들 때는
class 클래스이름: 형식으로 만들어 준다.

객체를 만들 때는
인스턴스면 = 클래스() 와 같이 만든다.

객체의 메서드를 사용하려면
객체.메서트 형식으로 사용한다.

>>> class Singer:                      # 가수를 정의하겠느니라…
...     def sing(self):                # 노래하기 메서드
...            return "Lalala~"
...    
>>> taeji = Singer()                   # 태지를 만들어랏!
>>> taeji.sing()                       # 노래 한 곡 부탁해요~
'Lalala~'

7.2 변수와 메서드

이번에는 클래스 내에 메서드와 변수를 생성해 보겠다.

class Amazon:
    strength = 20
    dexterity = 25
    vitality = 20
    energy = 15

    def attack(self):
        return 'Jab!!!'

위에 코드를 적은 파일을 diablo2.py 파일로 저장해준다.

>>> import diablo2
>>> jane = diablo2.Amazon()
>>> mary = diablo2.Amazon()

Amazon 클래스의 객체를 2개 생성하였다.

>>> jane.strength
20
>>> jane.attack()
'Jab!!!'

생성한 객체는 클래스에서 정의해준 변수와 메서드를 그대로 갖게 된다.

여기서 class 의 메소드 attack 에는 self라는 인자를 받았는데,
사용할 때는 인자 없이 attack()으로 사용하였다.

self라는 것은 바로 그 클래스의 객체를 가리킨다.
메서드를 정의할 때는 항상 self라는 인자를 써준다.

java의 this과 비슷한 역할이라고 생각하면 될 것 같다.

    def exercise(self):
        self.strength += 2
        self.dexterity += 3
        self.vitality += 1


7.3 상속

클래스를 상속 받으려면
class 클래스명(상위 클래스):
식으로 사용하면 된다.

class Student(Person):     # Person 클래스를 상속받음
    def study(self):
        print('열공열공...')

상속 받은 부모 클래스의 필드와 메서드를 그대로 물려 받는다.



7.4 객체 속의 객체

객체는 또 다른 객체를 포함할 수 있다.
객체지향 프로그래밍에서는 이런 것을 composition(합성, 복합)이라고 하고, 'has-a' 관계라고도 한다.

class Fridge:
    def __init__(self):
        self.isOpened = False
        self.foods = []

    def open(self):
        self.isOpened = True
        print('냉장고 문을 열었어요...')

    def put(self, thing):
        if self.isOpened:
            self.foods.append(thing)
            print('냉장고 속에 음식이 들어갔네...')
        else:
            print('냉장고 문이 닫혀있어서 못넣겠어요...')

    def close(self):
        self.isOpened = False
        print('냉장고 문을 닫았어요...')

class Food:
    pass

fridge.py 모듈을 만들었다.
음식 클래스처럼 쓸 것이 없을 땐 pass라고만 써주면 된다.

인터프리터를 이용해 냉장고에 코끼리를 넣자.

>>> import fridge
>>> f = fridge.Fridge()
>>> apple = fridge.Food()
>>> elephant = fridge.Food()

음식 클래스의 객체로 apple과 elephant 를 만들었다.

>>> f.open()
냉장고 문을 열었어요...
>>> f.put(apple)
냉장고 속에 음식이 들어갔네...
>>> f.put(elephant)
냉장고 속에 음식이 들어갔네...

냉장고 f에 apple 객체와 elephant 객체를 넣었다.

이제 냉장고 f의 foods 리스트를 살펴보면

>>> f.foods
[<fridge.Food instance at 007924AC>, <fridge.Food instance at 0079153C>]

food 클래스의 인스턴스 2개가 들어있다고 나온다.



7.5 특별한 메서드들


__init__ : 초기화

__init__ 메서드는 파이썬에서 특별하게 약속된 메서드 가운데 하나로, 초기화 메서드라고도 한다.

# bookstore.py

class Book:

    def setData(self, title, price, author):
        self.title = title
        self.price = price
        self.author = author

    def printData(self):
        print('제목 : ', self.title)
        print('가격 : ', self.price)
        print('저자 : ', self.author)

    def __init__(self):
        print('책 객체를 새로 만들었어요~')

어떤 클래스의 객체가 만들어질 때 자동으로 호출되어 그 객체가 갖게 될 여러가지 성질을 정해주는 일을 한다.
java의 생성자 메서드와 비슷하다고 보면 될 듯하다.


__del__ : 소멸자

__del__ 메서드는 __init__ 메서드와 반대로 객체가 없어질 때 호출한다.
소멸자의 역할을 한다.

어떤 객체가 없어지기 전에 뭔가 처리를 필요로 한다면 소멸자가 유용하게 쓰인다.


__repr__ : 프린팅

__repr__ 메서드는 '문자열'을 'return' 해준다.

    def __repr__(self):
        return self.title

java의 toString과 비슷한 역할인 것 같다.


__add__ : 덧셈

__add__ 메서드는 두 객체의 self 와 other 를 인자로 받아서 그 둘을 더한 값을 리턴한다.

# shape.py

class Shape:

    area = 0

    def __add__(self, other):
        return self.area + other.area

__sub__ 메서드로 두 객체의 뺄셈을 수행할 수 있다.


__It__ : 비교

__It__ 메서드는 두 개의 객체를 비교하는 연산자 >, <, = 를 쓸 수 있도록 해준다.

    def __lt__(self, other):
        return self.area < other.area

이러면 두 객체를 두 숫자를 비교하듯 부등호로 비교할 수 있다.

>>> import shape
>>> c = shape.Shape()
>>> c.area = 30
>>> d = shape.Shape()
>>> d.area = 20
>>> c > d
True
>>> if c > d: print('c가 더 넓어요~')
... 
c가 더 넓어요~


8. 예외


8.1 예외처리


예외처리는 try와 except 를 사용한다.

>>> def f(a, b):
...   try:
...     if a and b:
...       return (a * b) + (a / b)
...     elif a:
...       return '불능'
...     else:
...       return '부정'
...   except:
...     return '똑 바로 살아라'

오늘은 이렇게 파이썬의 파일을 다루는 법, 객체 지향, 예외를 다루는 법을 알아보았다.
셋 모두 자바에서 배웠던 개념이고, 코드의 형식만 조금 달라서 이해하기에 쉬웠다.

이로써 파이썬의 기본 문법은 모두 익힌 것 같다.
코딩테스트 문제를 풀면서 기본 문법에 더 익숙해질 필요가 있고, 책을 공부하며 모르는 코딩테스트 풀이법도 열심히 공부하도록 하겠다.

profile
프로그래밍 공부 블로그

0개의 댓글