[파이썬] 클래스, 모듈, 패키지, 예외 처리

osdsoonhyun·2022년 1월 29일
0

파이썬

목록 보기
7/10
post-thumbnail

클래스

변수 & 메서드(함수)를 미리 정해놓은 틀(설계도)

클래스는 도대체 왜 필요한가?

>>> 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))

클래스 쓰는 방법

  1. Class를 입력하고
  2. 대문자로 시작하는 클래스의 이름을 작성
  3. 안에 들어갈 함수와 변수 설정

파이썬 프로그래밍의 핵심,클래스

과자틀(클래스), 과자(객체)

사칙연산 클래스 만들기(+,-,*,/)

어떤 클래스를 만들지 그림을 그려보자

  • 사칙연산을 하려면 두 숫자를 입력받아야겠군!
    - setdata 매서드
  • 더하기 기능은?
    - add 메서드(+)
  • 곱하기 기능은?
    - mul 메서드(*)
  • 빼기 기능은?
    - sub 메서드(-)
  • 나누기 기능은?
    - div 메서드(/)
>>> 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에 들어간다

사칙연산 클래스 3

>>> 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

생성자(Constructor)

>>> 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은 상속 받은 자식 클래스가 된다
부모가 만든 것은 자식이 상속을 받아 다 똑같이 쓸 수 있다

클래스의 상속 2 - 메서드 추가

>>> 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

ifname == "main":의 의미

#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값이 나온 것

sys.path.append

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라는 함수만 불러오겠다

as활용하기

>>> from game.sound.echo import echo_test as e
>>> e()
echo

all

>>> 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

relative 패키지

>>> #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 Exception as e:
    -#오류 발생
  • else:
    -#오류 발생하지 않음
  • finally:
    -#무조건 마지막에 실행

try, except문

>>> try:
		...
>>> except [발생 오류[as 오류 메시지 변수]]    :
		...
>>> try:
	 	4 / 0
>>> except ZeroDivisionError as e:
		print(e)
>>> print("안녕하세요")
division by zero
안녕하세요

이렇게 하면 오류가 나도 프로그램이 안 꺼지기 때문에 밑에 코드가 정상적으로 나온다

try ... else

>>> try: 
>>> 	f = open('foo.txt', 'r')
>>> except FileNotFoundError as e:
>>> 	print(str(e))
>>> else:
>>> 	data = f.read()
>>> 	print(data)
>>> 	f.close

else는 try에 오류가 없을 때 실행해라

try ... finally

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
  

0개의 댓글