Jump to Python · · 10 min read
4. 파이썬 날개 달기, 클래스
1. 파이썬 프로그래밍의 핵심, 클래스
한 클래스로 만들어진 두 인스턴스는 독립적인 개체이다.
코드의 재사용이 쉬워진다.
객체와 인스턴스의 차이
- 클래스에 의해서 만들어진 객체를 인스턴스라고 한다.
- 객체 : Object
- 인스턴스 : 특정 객체가 어떤 클래스의 객체인지를 관계 위주로 설명할 때 사용
클래스 기초
- 클래스 변수
class Service: secret = "Top Secret" ob = Service() print(ob.secret)- Service 클래스가 제공하는 secret 변수를 사용할 수 있다.
- 클래스 함수
class Service: secret = "Top Secret" def sum(self, a, b): result = a + b print("{0} + {1} = {2}".format(a, b, result)) ob = Service() ob.sum(13, 15) - self
- 함수가 call 받았을 때 call한 객체가 클래스의 인스턴스인지 확인
ob = Service() ob.sum(ob, 13, 15) ob.sum(13, 15) # 같은 결과가 나온다.- 파이썬의 특징으로 클래스 내부 함수의 첫 번째 인수는 무조건 self로 해야 인스턴스 함수로 사용할 수 있다.
class Service: secret = "Top Secret" def setName(self, name): self.name = name def getName(self): return self.name ob = Service() ob.setName('Lee') print(ob.getName()) __init__- 인스턴스를 만들 때 항상 실행된다.
class Service: secret = "Top Secret" def __init__(self, name): self.name = name def getName(self): return self.name ob = Service('Lee') print(ob.getName())
- 클래스 변수
클래스 구조
- 다음과 같은 기본 구조를 갖고 있다.
class 클래스 이름[(상속 클래스명)]: <클래스 변수 1> <클래스 변수 2> ... <클래스 변수 n> def 클래스 함수1(self[, 인수1, 인수2, ...]): <수행할 문장 1> <수행한 문장 2> ... def 클래스 함수2(self[, 인수1, 인수2, ...]): <수행할 문장 1> <수행한 문장 2> ... def 클래스 함수3(self[, 인수1, 인수2, ...]): <수행할 문장 1> <수행한 문장 2> ..예제 : 사칙연산 클래스
class Cal: def setData(self, a, b): self.a = a self.b = b def sum(self): return self.a + self.b def div(self): return self.a / self.b def sub(self): return self.a - self.b def mul(self): return self.a * self.b예제 : ‘박씨네 집’ 클래스
class HousePark: lastname = "박" def __init__(self, name): self.setName(name) def setName(self, name): self.firstname = name self.fullname = self.lastname + name def travel(self, where): print("{0}, {1}여행을 간다.".format(self.fullname, where))상속
- ‘물려받다’라는 뜻으로 어떤 클래스를 만들 때 다른 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있게 만드는 것이다.
class HouseLee(HousePark): lastname = "이" ob = HouseLee("파이") ob.travel("영동")메서드 오버라이딩(method overriding)
- 함수를 상속받았을 때 이름은 같지만 다른행동을 하게 할 때
class HouseLee(HousePark): lastname = "이" def travel(self, where, day): print("{0}, {1}여행 {2}일 가네.".format(self.fullname, where, day)) ob = HouseLee("파이") ob.travel("영동", 13) # ob.travel("서해안") 에러!연산자 오버로딩(operator overloading)
- 연산자를 객체끼리 사용할 수 있게 하는 기법이다.
class HousePark: lastname = "박" def __init__(self, name): self.setName(name) def setName(self, name): self.firstname = name self.fullname = self.lastname + name def travel(self, where): print("{0}, {1}여행을 간다.".format(self.fullname, where)) def __add__(self, other): print("{0}과 {1}은 결혼했다.".format(self.fullname, other.fullname)) a = HousePark("노을") b = HousePark("가을") a + b
2. 모듈
- 모듈이란?
- 함수나 변수 또는 클래스들을 모아 놓은 파일이다. 모듈은 다른 파이썬 프로그램에서 불러와 사용할 수 있게끔 만들어진 파이썬 파일이라고도 할 수 있다.
- 다른 사람들이 이미 만들어 놓은 모듈을 사용할 수도 있고, 우리가 직접 만들어서 사용할 수도 있다.
- 모듈 만들고 사용하기
# mod1.py def sum(a, b): return a + b # root 디렉토리 아래 Python 디렉토리를 생성하고 디렉토리 안에 저자한다.- mod1.py를 저장한 위치로 이동한 다음 이후 예제를 진행해야 대화형 인터프리터에서 mod1.py를 읽을 수 있다.
import mod1 # 모듈을 불러는 방법 print(mod1.sum(3, 4)) - 모듈 함수를 사용하는 또 다른 방법 :
from 모듈이름 import 모듈함수 if __name__ == "__main__":의 의미- 직접 실행했을 때 실행할 코드를 의미한다.
# mod1.py PI = 3.141592 class Math: def solv(self, r): return PI * (r ** 2) def sum(a, b): return a + b # 직접 실행했을 때 아래 코드를 실행시키겠다. if __name__ == "__main__": print(PI) a = Math() print(a.solv(3)) print(sum(PI, 4.4))- 모듈을 불러오는 또 다른 방법
- sys.path.append(모듈을 저장한 디렉토리) 사용
>>>import sys >>>sys.path >>>sys.path.append("모듈로 사용할 py파일을 저장한 디렉토리")- PYTHONPATH 환경변수 사용하기
# 모듈로 사용할 py파일을 저장한 디렉토리를 PYTHONPATH 환경변수에 추가한다. set PYTHONPATH=C:\Python\Mymodule
3. 패키지
패키지
- 도트(.)를 이용하여 파이썬 모듈을 계층적(디렉토리 구조)으로 관리할 수 있게 해준다.
- 파이썬 패키지는 디렉토리와 파이썬 모듈로 이루어진다.
- 패키지 구조로 파이썬 프로그램을 만드는 것이 공동작업이나 유지보수 등 여러 면에서 유리하다.
- 패키지 구조로 모듈을 만들면 다른 모듈과 이름이 겹치더라도 더 안전하게 사용할 수 있다.
패키지 만들기
패키지 기본 구성 요소 준비하기
__init__.py는 비어있는 상태로 둔다.
# echo.py def echo_test(): print("echo")# render.py def render_test(): print("render")- PYTHONPATH 환경변수에 등록한다.
패키지 안의 함수 실행하기
# echo 모듈을 import하여 실행 import game.sound.echo game.sound.echo.echo_test()# echo 모듈이 있는 디렉터리까지를 from .. import하여 실행 from game.sound import echo echo.echo_test()# echo_test 함수를 직접 import하여 실행 from game.sound.echo import echo_test() echo_test()- 아래와 같이는 불가능하다
import game # game 디렉토리의 모듈 또는 game 디렉토리의 game.sound.echo.echo_test() # __init__.py에 정의 된 것들만 참조 가능import game.sound.echo.echo_test # 도트 연산자를 사용해서 import a.b.c 처럼 import할 때 가장 마지막 항목인 # c는 반드시 모듈 또는 패키지여야만 한다.__init__.py의 용도- 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다.
- game, sound, graphic 등의 패키지에 포함된 디렉토리에
__init__.py파일이 없다면 패키지로 인식되지 않는다.
__all__의 용도from game.sound import * echo.echo_test() # 오류 발생!!!- 특정 디렉토리의 모듈을 *를 이용하여 import할 때에는 다음과 같이 해당 디렉토리의
__init__파일에__all__이라는 변수를 설정하고 import할 수 있는 모듈을 정의해 주어야한다.
- 특정 디렉토리의 모듈을 *를 이용하여 import할 때에는 다음과 같이 해당 디렉토리의
relative 패키지
- 만약 graphic 디렉토리의 render.py 모듈일 sound 디렉토리의 echo.py 모듈을 사용하고 싶다면 render.py를 다음과 같이 수정한다.
# render.py from game.sound.echo import echo_test def render_test(): print("render") echo_test()# render.py from ..sound.echo import echo_test def render_test(): print("render") echo_test()- ..과 같은 relative한 접근자는 render.py와 같이 모듈 안에서 사용해야 한다. 파이썬 인터프리터에서 사용하면 오류가 발생한다.
4. 예외 처리
- 예외 처리 : 오류가 발생했을 때의 동작을 수정할 수 있다.
- 오류 예외 처리 기법 : try, except
- try : 시도한다…
- except : 오류가 발생하면…
except [발생 오류[as 오류 메시지 변수]]:
try: ... except: ...try: ... except 발생 오류: ...try: ... except 발생 오류 as 오류 메시지 변수: ...- 예시
try: a = 4 / 0 except ZeroDivisionError as e: print(e)
- 오류 예외 처리 기법 : try .. else
- else절은 예외가 발생하지 않은 경우 실행되며 반드시 except절 바로 다음에 위치해야 한다.
try: f = open('foo.txt', 'r') except FileNotFoundError as e: print(e) else: data = f.read() f.close() - 오류 예외 처리 기법 : try .. finally
- finally절은 try문 소행 도중 예외 발생 여부에 상과 없이 항상 수행된다.
- 보통 finally절은 사용한 리소스를 close해야 할 경우에 많이 사용된다.
f = open('foo.txt', 'w') try: # 무언가를 수행한다. finally: f.close() - 오류 회피하기
- 특정 오류가 발생한 경우 그냥 통과시켜야 할 때가 있을 수 있다.
try: f = open('없는 파일', 'r') except FileNotFoundError: pass - 오류 일부러 발생시키기
raise를 사용하여 오류를 일부러 발생시킬 수 있다.
class Bird: def fly(self): raise NotImplementedError class Eagle(Bird): def fly(self): # 만들지 않았다면 오류가 발생한다! print('very fast')
5. 내장 함수
- 아무런 설정 없이 바로 사용할 수 있다.
- abs(x)
- 절대값을 반환
- all(x)
- 반복 가능한 자료형 x를 입력 인수로 받아 모두 참이면 True, 하나라도 거짓이 있다면 False를 반환
- any(x)
- 반복 가능한 자료형 x를 입력 인수로 받아 하나라도 참이 있면 True, 모두 거짓이라면 False를 반환
- chr(i)
- 아스키 코드값을 입력으로 받아 그 코드에 해당하는 문자를 반환
- ord(c)
- 문자를 입력으로 받아 그 문자에 해당하는 아스키 코드를 반환
- divmod(a, b)
- 2개의 숫자를 입력으로 받아 a를 b로 나눈 몫과 나머지를 튜플 형태로 반환
- enumerate
- 순서가 있는 자료형을 입력으로 받아 인덱스 값을 포함하는 enumerate 객체를 반환
for i, name in enumerate(['body', 'your', 'hot']): print(i, name) - eval(expression)
- 실행 가능한 문자열(1+2, ‘hi’+‘a’)을 입력으로 받아 문자열을 실행한 결과값을 반환
- 입력받은 문자열로 파이썬 함수나 클래스를 동적으로 실행하고 싶은 경우에 사용된다.
- filter(함수이름, 함수에 들어갈 반복 가능한 자료형)
- 두 번째 인수인 반복 가능한 자료형 요소들이 첫 번째 인수인 함수에 입력되었을 때 리턴값이 참인 것만 묶어서 돌려준다.
def positive(numberList): result = [] for num in numberList: if num > 0: result.append(num) return result print(positive([1, -3, 2, 0, -5, 6]))def positive(x): return > 0 print(list(filter(postive,[1, -3, 2, 0, -5, 6]))) - id(object)
- 객체를 입력받아 객체의 고유 주소값(레퍼런스)을 반환
- input([prompt])
- 사용자 입력을 받는다.
- int(x), int(x, radix)
- int(x) : 문자열 형태의 소수나 소수점 있는 숫자 등을 정수로 반환
- int(x, raidx) : 진수로 표현된 문자열s를 10진수로 변환하여 반환
print(int('10A', 16)) - isinstance(object, class)
- 첫 번째 인수로 인스턴스, 두 번째 인수로 클래스 이름을 받아 인스턴스가 클래스의 인스턴스인지 판단하여 참이면 True, 거짓이면 False를 반환
- lambda
- 함수를 생성할 때 사용하는 예약어
- def와 동일한 역할을 한다.
- 함수를 한줄로 간결하게 만들 대 사용한다.
- def를 사용할 수 없는 곳에 주로 쓰인다.
- 생성 :
lambda 인수1, 인수2, ...: 인수를 이용한 표현식
sum = lambda a, b: a + b print(sum(3, 4))# 리스트 내에서도 사용 가능하다. myList = [lambda a, b: a + b, lambda a, b: a * b] print(myList[0](3, 4)) # 덧셈 print(myList[1](3, 4)) # 곱셈 - len(s)
- 입력값 s의 길이(요소의 전체 개수)를 반환
- list(s)
- 반복 가능한 자료형 s를 입력받아 리스트로 만들어 반환
- map(f, iterable)
- 함수(f)와 반복 가능한(iterable) 자료형을 입력으로 받는다.
- map은 입력 받은 자료형의 각 요소와 함수 f에 의해 수행된 결과를 묶어서 반환
def two_times(numberList): result = [] for number in numberList: result.append(number * 2) return result res = two_times([1, 2, 3, 4]) print(res)def two_times(x): return x * 2 print(list(map(two_times, [1, 2, 3, 4])))print(list(map(lambda a: a * 2, [1, 2, 3, 4]))) - max(iterable)
- 반복 가능한 자료형을 입력받아 그 최대값을 반환
- min(iterable)
- 반복 가능한 자료형을 입력받아 그 최소값을 반환
- oct(x)
- 정수 형태의 숫자를 8진수 문자열로 바꾸어 반환
- hex(x)
- 정수값을 입력받아 16진수로 변환하여 반환
- open(filename, [mode])
- 파일이름과 읽기 방법을 입력받아 파일 객체를 반환
- pow(x, y)
- x의 y승한 결과값을 반환
- range([start,] end[, step])
- for문과 함께 자주 사용되는 함수
- 입력받은 숫자에 해당하는 범위를 반복 가능한 객체로 만들어 반환
- 인수가 하나일 경우
print(list(range(10)))- 인수가 2개일 경우
print(list(range(0, 10)))- 인수가 3개일 경우
print(list(range(0, 10, 2))) - sorted(iterable)
- 입력갑을 정렬한 후 그 결과를 리스트로 반환
numlist = [3, 6, 2, 8, 1] print(sorted(numlist)) print(numlist) numlist.sort() print(numlist()) - str(object)
- 문자열 형태로 객체를 변환하여 반환
- tuple(iterable))
- 반복 가능한 자료형을 입력받아 튜플 형태로 변환하여 반환
- type(object)
- 입력값의 자료형이 무엇인지 알려주는 함수
- zip(iterable*)
- 동일한 개수로 이루어진 자료형을 묶어 주는 역할을 하는 함수
list(zip([1, 2, 3], [4, 5, 6]))
6. 외장 함수
p251
sys 모듈
- 명령 행에서 인수 전달 : sys.argv
- 강제로 스크립트 종료 : sys.exit
- 자신이 만든 모듈 불러와 사용하기 : sys.path
pickle 모듈
- 객체의 형태를 그대로 유지하면서 파일에 저장하고 불러올 수 있게하는 모듈
os 모듈
- 환경변수, 디렉토리, 파일등의 os자원을 제어할 수 있게 해주는 모듈
- 시스템의 환경변수값을 알고 싶을 때 : os.environ
- 디렉토리 위치 변경하기 : os.chdir
- 디렉토리 위치 반환받기 : os.getcwd
- 시스템 명령어 호출하기 : os.system
- 실행한 시스템 명령어의 결과값 반환받기 : os.popen
- 디렉토리 생성 : os.mkdir
- 디렉토리 삭제 : os.rmdir
- 파일 삭제 : os.unlink
- 파일이름 변경 : os.rename
shutil 모듈
- 파일을 복사해 주는 파이썬 모듈
- 파일 복사 : shutil.copy
glob 모듈
- 디렉토리에 있는 파일들을 리스트로 만들기 : glob
tempfile 모듈
- 파일을 임시로 만들어 사용할 때 유용한 모듈
- 임시 파일의 이름을 무작위로 만들어 반환 : tempfile.mktemp
- 임시 저장 공간으로 사용될 파일 객체를 반환 : tempfile.TemporaryFile
time 모듈
- 시간과 관련된 모듈
- UTC 기준으로 실수형태로 시간을 반환 : time.time
- 년, 달, 월, 일, 시, 분, 초, … 형태로 바꾸어주는 함수 : time.localtime
- time.localtime에 의해서 반환된 튜플 형태의 값을 인수로 받아 날짜와 시간을 알아보기 쉬운 형태로 반환 : time.asctime
- time.ctime
- time.strftime
- time.sleep
calendar 모듈
- 달력과 관련된 모듈
random 모듈
- 랜덤값(난수)을 생성하기 위한 모듈
webbrowser 모듈
- 자신의 시스템에서 사용하는 기본 웹 브라우저가 자동으로 실행되게 하는 모듈
import webbrowser webbrowser.open("http://google.com")theading 모듈
- 쓰레드와 관련된 모듈
- 한 프로그램에서 2가지 이상의 일을 동시에 수행하도록 할 수 있다.
import threading import time def say(msg): while True: time.sleep(1) print(msg) for msg in ['you', 'need', 'python']: t = threading.Thread(target=say, args=(msg,)) t.daemon = True t.start() for i in range(100): time.sleep(0.1) print(i)import threading import time class MyThread(threading.Thread): def __init__(self, msg): threading.Thread.__init__(self) self.msg = msg self.daemon = True def run(self): while True: time.sleep(1) print(self.msg) for msg in ['you', 'need', 'python']: t = MyThread(msg) t.start() for i in range(100): time.sleep(0.1) print(i)