클래스
변수 & 메서드(함수)를 미리 정해놓은 틀(설계도)
>>> result = 0
>>> def add(num):
>>> global result
>>> result += num
>>> return result
>>> print(add(3))
3
>>> print(add(4))
7
이렇게 한 개 일때는 괜찮으나 두 개 이상일 때 문제가 된다
두 개의 계산기
>>> result1 = 0
>>> result2 = 0
>>> def add1(num):
>>> global result1
>>> result1 += num
>>> return result1
>>> def add2(num):
>>> global result2
>>> result2 += num
>>> return result2
>>> print(add1(3))
3
>>> print(add1(4))
7
>>> print(add2(3))
3
>>> print(add2(7))
10
클래스
로 이것을 만들 수 있다 즉! 더하기라는 걸 클래스로 만들어서 함수를 하나씩 매번 똑같은 함수를 생성하는게 아니라 클래스라는 걸 만들고 클래스를 이용해서 똑같이 생기는거는 여러개 instance
를 찍어낸다
클래스는 함수랑 변수가 똑같은 구조를 계속 여러번 써야되니 이것을 하나로 묶어서 설계도
로 만든 것
>>> class Calculator // class의 첫 알파벳은 대부분 대문자
>>> def __init__(self):
>>> self.result = 0
>>> def add(self,num):
>>> self.result += num
>>> return self.result
>>> cal1 = Calculator()
>>> cal2 = Calculator()
>>> print(cal1.add(3))
>>> print(cal1.add(4))
>>> print(cal2.add(3))
>>> print(cal2.add(7))
클래스 쓰는 방법
과자틀(클래스), 과자(객체)
어떤 클래스를 만들지 그림을 그려보자
>>> class FourCal: // 첫 글자는 대문자
def setdata(self, first,second): //self는 a
self.first = first //a의 변수에 first 대입
self.second = second
>>> a = FourCal()
>>> a.setdata(1,2) //a에 있는 함수를 쓰겠다해서 a.~~
>>> print(a.first)
1
>>> print(a.second)
2
class 안에 있는 함수(메서드)를 self에 들어간다
>>> class FourCal:
>>> def setdata(self,first,second):
>>> self.first = first
>>> self.second =second
>>> def add(self):
>>> result = self.first+self.second
>>> return result
>>> a = FourCal()
>>> a.setdata(4,2)
>>> print(a.add())
6
>>> class Fourcal:
>>> def__init__(self,first,second):
>>> self.first = first
>>> self.second = second
>>> def setdata(self,first,second):
>>> self.first = first
>>> self.second = second
>>> def add(self):
>>> result = self.first + self.second
>>> return result
>>> a = FourCal(1,2)
__init__
은 예약어로 시작하는 함수로 쓰게되면 이걸 선언할 때 무조건 맨 처음
에 실행된다
부모를 상속 받아서 자식 클래스를 만든다
>>> class MoreFourCal(FourCal): //괄호 안에 부모 클래스
>>> pass
>>> a = MoreFourCal(4,2)
>>> print(a.add())
6
MoreFourCal은 상속 받은 자식 클래스가 된다
부모가 만든 것은 자식이 상속을 받아 다 똑같이 쓸 수 있다
>>> class MoreFourCal(FourCal):
>>> def pow(self):
>>> result = self.first ** self.second
>>> return result
>>> a = MoreFourCal(4,2)
>>> print(a.pow)
16
부모의 함수를 덮어쓴다
>>> class SafeFourCal(FourCal): //새로운 자식
>>> def div(self): // div가 있는데 한번 더 정의
>>> if self.second == 0:
>>> return 0
>>> else:
>>> return self.first/ self.second
>>> a = SafeFourCal(4,2)
>>> print(a.pow())
2.0
>>> b = SafeFourCal(4,0)
>>> print(b.div())
0
div가 부모에 있는데 자식에 한 번 더 정의하면 자식
이 우선시
된다
자식 이기는 부모는 없다!
결국에는 상속 받는 이유가 부모거를 가져다가 변형해서 자기만의 클래스르 만들기 위함이다
>>> class Family:
>>> lastname = "김"
>>> Family.lastname = "박"
>>> print(Family.lastname)
>>> a = Family()
>>> b = Family()
>>> print(a.lastname)
박
>>> print(b.lastname)
박
Family라는 클래스 자체를 바꿨기 때문에 설계도가 바뀌었기에 찍어내는 a,b 둘다 '박'으로 출력됨
클래스 변수와 객체변수의 차이
>>> class FourCal:
first = 2 // 클래스 변수
second = 3 // 클래스 변수
>>> def setdata(self,first,second): // 객체변수
>>> self.first = first // 객체변수
>>> self.second =second // 객체변수
>>> def add(self):
>>> result = self.first+self.second
>>> return result
모듈이란?
미리 만들어 놓은 .py파일
로 함수랑 변수, 클래스를 미리 파일 하나에 만들어 놓고 가져다 사용할 수 있게 만든 것
#mod1.py
>>> def add(a,b):
>>> return a+b
#hello.py
>>> import mod1
>>> print(mod1.add(1,2))
3
mod1.py에 만들어 놓은 함수를 import해서 가져다가 사용 가능하다
mo1.py의 여러개의 함수 중에서 하나만 가지고 오고 싶을 때
#mod1.py
>>> def add(a,b):
>>> return a+b
>>> def div(a,b):
>>> return a/b
...
#hello.py
>>> from mod1 import add
>>> print(add(1,2))
3
#mod1.py
>>> def add(a,b):
>>> return a+b
>>> def sub(a,b):
>>> return a-b
>>> if__name__ == "__main__":
>>> print(add(1,4))
>>> print(add(4,2))
#hello.py
//if__name__ == "__main__": //주석처리 했을 경우 시험삼아 해놨던 print 결과값이 나온다
>>> import mod1
5
6
>>> import m
__name__이 실행하는 함수의 이름과 일치할 때 if문에 있는 print를 실행하도록 한 것
#mod1.py
>>> def add(a,b):
>>> return a+b
>>> def sub(a,b):
>>> return a-b
>>> if__name__ == "__main__":
>>> print(add(1,4))
>>> print(add(4,2))
5
6
시작하려는 파일이 main이라는 이름으로 시작하였기 때문에 print값이 나온 것
import를 할 때 같은 경로에 있으면 괜찮으나 하위폴더나 상위폴더, 다른 경로에 있을 때는 path에 추가를 해주어야 한다
경로에 내가 가져올려는 import하려는 거는 subfolder 안에 있다라고 알려줘야 한다
>>> import sys
>>> sys.path.append("C:\\jocoding\\subFolder")
>>> import mod1
>>> print(mod1.add(3,4))
7
패키지 = 라이브러리
패키지란 모듈 여러 개 모아놓은 것
가상의 game 패키지 예
>>> game/
>>> __init__.py //패키지를 표현하는 파이썬 파일
>>> sound/
>>> __init__.py
>>> echo.py
>>> graphic/
>>> __init__.py
>>> render.py
init.py 안에 패키지 관련 설정 하는 곳
>>> import game.sound.echo
>>> game.sound.echo.echo_test()
모듈일 때는 같은 파일이니 import하고 파일을 부르면 됐으나, 패키지는 폴더이므로 하나씩 들어가야 한다
>>> from game.sound import echo
>>> echo.echo_test()
echo
모듈과 마찬가지로 함수 여러개 중 하나만 불러올 때 from 모듈이름 import 함수
>>> from game.sound.echo import echo_test
>>> echo_test()
echo
game이라는 패키지 안에 sound라는 폴더 안에 echo를 불러오는데 그 중에서 echo_test라는 함수만 불러오겠다
>>> from game.sound.echo import echo_test as e
>>> e()
echo
>>> from game.sound import *
>>> echo.echo_test()
>>> Traceback(most recent call last):
>>> File "<stdin>", line 1, in <module>
>>> NameError: name 'echo' is not defined
*
를 쓰게 되면 __init__.py에 기록해놓은 것을 모두 불러와라
# C:/game/sound/__init__.py
>>> __all__ = ['echo','echo2']
### hello.py
>>> from game.sound import *
>>> echo.echo_test()
echo
>>> #render.py
>>> from ..sound.echo import echo_test
>>> def render_test():
>>> print("render")
>>> echo_test()
graphic이라는 폴더가 아닌 밖에 나가서 sound라는 폴더 안에 echo를 불러오고 싶다
../
이 상대 경로에서 이전 폴더로 돌아간다
지금 graphic폴더 안에 render.py에 있는데, ../
을 통해 이전 폴더인 game 안에 sound에 들어가고 sound 안에 echo라는 모듈을 가져오겠다
예외처리
오류가 발생했을때 어떻게 할지 정하는 것
원래 오류가 발생하면 프로그램이 꺼지는데, 그 오류를 어떻게 처리해서 넘어가게끔 만든 것이다
>>> try:
...
>>> except [발생 오류[as 오류 메시지 변수]] :
...
>>> try:
4 / 0
>>> except ZeroDivisionError as e:
print(e)
>>> print("안녕하세요")
division by zero
안녕하세요
이렇게 하면 오류가 나도 프로그램이 안 꺼지기 때문에 밑에 코드가 정상적으로 나온다
>>> try:
>>> f = open('foo.txt', 'r')
>>> except FileNotFoundError as e:
>>> print(str(e))
>>> else:
>>> data = f.read()
>>> print(data)
>>> f.close
else는 try에 오류가 없을 때 실행해라
try -> 오류날 수 있는 것을 실행하는 거
except -> 오류 났을 때 잡는 거
finally -> 오류와 관계없이 마지막에 실행하는 거
>>> f = open('foo.txt','w')
>>> try:
>>> # 무언가를 수행한다.
>>> finally:
>>> f.close()
>>> f = open('foo.txt','w')
>>> try:
>>> # 무언가를 수행한다.
>>> data = f.read()
>>> print(data)
>>> except Exception as e:
>>> print(e)
>>> finally:
>>> f.close()
exception은 뭐가 발생할지 모르므로 Exception이 모든 오류의 부모이므로 어떤 오류든 잡아준다
>>> try:
>>> f = open("나없는파일",'r')
>>> except FileNotFoundError:
>>> pass