
오늘도 파이썬 알고리즘 공부에 앞서 파이썬 기본 문법을 살펴보겠다.
오늘 살펴볼 파이썬 기본 문법은 파일, 객체지향, 예외이다.
이전과 같이 https://wikidocs.net/85 를 참고하였다.
파이썬에서 텍스트 파일을 다룰 수 있다.
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()
파일을 처음부터 끝까지 읽을 땐 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']
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는 파일들의 리스트를 뽑을 때 사용하는데, 파일의 경로명을 이용해서 입맛대로 요리할 수 있다.
>>> from glob import glob
>>> glob('*.exe') # 현재 디렉터리의 .exe 파일
['python.exe', 'pythonw.exe']
>>> glob('*.txt') # 현재 디렉터리의 .txt 파일
['LICENSE.txt', 'NEWS.txt']
glob() 함수는 인자로 받은 패턴과 이름이 일치하는 모든 파일과 디렉터리의 리스트를 반환한다. 패턴을 그냥 *라고 주면 모든 파일과 디렉터리를 볼 수 있다.
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
객체 지향의 개념은 자바를 통해 많이 공부했으므로 기본적인 설명은 넘어가겠다.
클래스를 만들 때는
class 클래스이름: 형식으로 만들어 준다.
객체를 만들 때는
인스턴스면 = 클래스() 와 같이 만든다.
객체의 메서드를 사용하려면
객체.메서트 형식으로 사용한다.
>>> class Singer: # 가수를 정의하겠느니라…
... def sing(self): # 노래하기 메서드
... return "Lalala~"
...
>>> taeji = Singer() # 태지를 만들어랏!
>>> taeji.sing() # 노래 한 곡 부탁해요~
'Lalala~'
이번에는 클래스 내에 메서드와 변수를 생성해 보겠다.
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
클래스를 상속 받으려면
class 클래스명(상위 클래스):
식으로 사용하면 된다.
class Student(Person): # Person 클래스를 상속받음
def study(self):
print('열공열공...')
상속 받은 부모 클래스의 필드와 메서드를 그대로 물려 받는다.
객체는 또 다른 객체를 포함할 수 있다.
객체지향 프로그래밍에서는 이런 것을 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개가 들어있다고 나온다.
__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__ 메서드는 __init__ 메서드와 반대로 객체가 없어질 때 호출한다.
소멸자의 역할을 한다.
어떤 객체가 없어지기 전에 뭔가 처리를 필요로 한다면 소멸자가 유용하게 쓰인다.
__repr__ 메서드는 '문자열'을 'return' 해준다.
def __repr__(self):
return self.title
java의 toString과 비슷한 역할인 것 같다.
__add__ 메서드는 두 객체의 self 와 other 를 인자로 받아서 그 둘을 더한 값을 리턴한다.
# shape.py
class Shape:
area = 0
def __add__(self, other):
return self.area + other.area
__sub__ 메서드로 두 객체의 뺄셈을 수행할 수 있다.
__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가 더 넓어요~
예외처리는 try와 except 를 사용한다.
>>> def f(a, b):
... try:
... if a and b:
... return (a * b) + (a / b)
... elif a:
... return '불능'
... else:
... return '부정'
... except:
... return '똑 바로 살아라'
오늘은 이렇게 파이썬의 파일을 다루는 법, 객체 지향, 예외를 다루는 법을 알아보았다.
셋 모두 자바에서 배웠던 개념이고, 코드의 형식만 조금 달라서 이해하기에 쉬웠다.
이로써 파이썬의 기본 문법은 모두 익힌 것 같다.
코딩테스트 문제를 풀면서 기본 문법에 더 익숙해질 필요가 있고, 책을 공부하며 모르는 코딩테스트 풀이법도 열심히 공부하도록 하겠다.