[점프투파이썬] 5장 파이썬 날기(1) - 클래스, 모듈, 패키지, 예외처리 정리

해롱그·2023년 6월 9일
0

파이썬

목록 보기
5/12
post-thumbnail

1. 클래스


반복되는 변수 & 메서드(함수)를 미리 정해놓은 틀(설계도)
함수랑 변수가 똑같은 구조를 계속 여러번 써야되니까 아싸리 하나로 묶어서 그냥 설계도로 만들어보자! 해서 만든게 클래스

  • 클래스 사용 방법
  1. class를 입력하고
  2. 대문자로 시작하는 클래스의 이름을 작성
  3. 안에 들어갈 함수와 변수 설정
  • 클래스가 왜 필요한가?
result = 0
def add(num):
    global result
    result += num
    return result
print(add(3))
print(add(4))

>>> 3
	7

이처럼 한개를 계산할 때는 괜찮음
but, 아래와 같이 2개 이상을 계산하고 싶을 때라면?

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))
print(add1(4))
print(add2(3))
print(add2(7))

>>> 3
	7
    3
    10

똑같은 함수인데 여러번 써야하는 불편함 존재 -> 클래스 사용!

class Calculator:
    def __init__(self):
        self.result = 0
    
    def add(self, num):
        self.result += num
        return self.result

cal1 = Calculator()		#설계도로 만든 어떤 결과물이 찍어져서(인스턴스) cal1에 들어감
cal2 = Calculator()

print(cal1.add(3))
print(cal1.add(4))
print(cal2.add(3))
print(cal2.add(7))

>>> 3
	7
    3
    10

💡 example 1

class FourCal:
    def setdata(self, first, second):
        self.first = first
        self.second = second

a = FourCal()
a.setdata(1, 2)
print(a.first)
print(a.second)

>>> 1
	2

💡 example 2

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)

__init__ : 클래스를 처음 만들 때 이닛이라고 시작하는 함수를 쓰게 되면 클래스 선언 시 무조건 맨 처음으로 실행함

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)

클래스의 상속

계산기(부모)를 이용해서 공학용계산기(자식)를 만드는 것과 비슷!
구현해놓은 기능은 그대로 사용하고, 추가적인 내용만 추가하면 됨

기존에 짠 class를 그대로 활용하기 위해 상속을 사용한다.

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

class MoreFourCal(FourCal):
    pass

a = MoreFourCal(4, 2)
print(a.add())

>>> 6

-> 부모가 만든건 자식이 상속 받으면 다 똑같이 사용할 수 있다!

# 1. 메서드 추가

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

class MoreFourCal(FourCal):
    def pow(self):				#메서드 추가 부분!
        result = self.first ** self.second
        return result

a = MoreFourCal(4, 2)
print(a.pow())

>>> 16

# 2. 메서드 오버라이딩(변형, 부모의 함수를 자식이 덮어쓴다.)
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
    def mul(self):
        result = self.first * self.second
        return result
    def sub(self):
        result = self.first - self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

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.div())

>>> 2.0

클래스 변수 vs 객체 변수

  • 클래스 변수 : 클래스에 미리 선언해놓은 변수로 클래스에 공통적으로 적용됨
class FourCal:
	# 클래스 변수
    first = 2
    second = 3

💡 example

class Family:
    lastname = "김"

Family.lastname = "박"
print(Family.lastname)

a = Family()
b = Family()
print(a.lastname)
print(b.lastname)

>>> 박
	박
    박
  • 객체 변수
class FourCal:
	# 객체 변수
    def __init__(self, first, second):
        self.first = first
        self.second = second

공통으로 쓸 때는 클래스 변수를 사용하고, 각각 객체마다 다르게 줄 때는 객체 변수를 사용한다!!

2. 모듈

미리 만들어 놓은 .py(파이썬) 파일 (함수, 변수, 클래스)

모듈의 사용법

(1) import 해서 사용!

>>> 7

(2) from 모듈이름 import 모듈함수 사용!
모듈안에 함수가 여러 개인데 그 중 하나만 골라서 사용하고 싶은 경우에 씀

>>> 12

if__name__ == "__main__": 의 의미

없을 때

>>> 5
	6

5, 6이 찍히는 이유-> import mod1 하면서 mod1.py에 있는 print~ 코드(8,9 라인)까지 실행되기 때문에!

if __name__ == "__main__":

를 추가해주면 hello.py

import mod1

를 실행해도 mod1.py의 print(add(1,4)), print(add(4,2))가 실행되지 않음!

sys.path.append

import 할 때 같은 경로에 있지 않고 다른 경로에 있을 경우
즉, 내가 import 하려고 하는 것이 다른 폴더 안에 있다면 그걸 알려줘야 한다!

  • mod2.py

  • hello.py

import sys
sys.path.append("/Users/(실명이라..ㅎ)/eclipse-workspace/jocoding/subFolder")
import mod2
print(mod2.mul(4,5))

>>> 20

but, 경로 안쓰면 error!

import mod2
print(mod2.mul(4,5))

>>> <module>
    	import mod2
	ModuleNotFoundError: No module named 'mod2'

🔅 쉽게 경로 복사 하는 법

3. 패키지 ≒ 라이브러리

모듈 여러 개 모아 놓은 것

💡 가상의 game 패키지 example

__init__.py : 패키지 관련 설정 하는 파일
패키지를 구성할 때도 이닛을 써서 패키지를 구성해서 설정들을 해놓을 수 있음!
🔅 파이썬 3.3버전 이후로는 init 안써줘도 됨

테스트를 위해 패키지 만들기

# game/sound/echo.py
def echo_test():
    print("echo")

# game/graphic/render.py
def render_test():
    print("render")

패키지 안의 함수 실행하기

import game.sound.echo
game.sound.echo.echo_test()

>>> echo

# 다른 방법 1
from game.sound import echo
echo.echo_test()

>>> echo

# 다른 방법 2
from game.sound.echo import echo_test
echo_test()

>>> echo

# 다른 방법 3
from game.sound.echo import echo_test as e
e()

>>> echo

all

__init__.py 에 *를 쓰게 되면 뭘 가져올건지 기록을 해놓을 수 있음

# game/sound/__init__.py
__all__ = ['echo']  # *를 썼을 때 가져오는 것!
from game.sound import *
echo.echo_test()

>>> echo

relative 패키지

.. : 이전 폴더로 가는 경로 표시

# game/graphic/render.py
from ..sound.echo import echo_test

def render_test():
    print("render")
    echo_test()

# 실행
from game.graphic import render
render.render_test()

>>> render
	echo

4. 예외처리

오류가 발생했을 때 어떻게 할지 미리 정해놓는 것
에러가 발생할 수 있는 구문에 조치를 미리 취해놓기!

예외처리 기본 구조

  • try: 오류가 발생할 수 있는 구문
  • except Exception as e: 오류 발생
  • else: 오류 발생하지 않음
  • finally: 무조건 마지막에 실행
f = open("없는파일", 'r')

>>> FileNotFoundError: [Errno 2] No such file or directory: '없는파일' #오류

예외처리 종류

💡 example

4 / 0
print("이 글이 보이면 예외처리가 성공적으로 된 것!")

>>> ZeroDivisionError: division by zero		#error 발생

# try..except
try:
    4 / 0
except ZeroDivisionError as e:
    print(e)

print("이 글이 보이면 예외처리가 성공적으로 된 것!")

>>> division by zero
	이 글이 보이면 예외처리가 성공적으로 된 것!
    
# try..else
try:
    f = open("none", 'r')
except FileNotFoundError as e:  #위 파일이 없을 때
    print(str(e))
else:   #위 파일이 있을 때
    data = f.read()
    print(data)
    f.close()

print("이 글이 보이면 예외처리가 성공적으로 된 것!")

>>> [Errno 2] No such file or directory: 'none'
	이 글이 보이면 예외처리가 성공적으로 된 것!
    
# foo.txt
안녕!

# try..finally
f = open('foo.txt', 'r')
try:
    #무언가를 수행
    data = f.read()
    print(data)
except Exception as e:  #오류 났을 때 잡는 구문
    print(e)
finally:    # 오류와 상관없이 무조건 마지막에 실행하는 구문
    f.close()

>>> 안녕!

🔅 Exception : 모든 오류의 부모, 어떤 오류가 날지 모를 경우엔 얘를 사용해주기~
어떤 에러든 다 잡을 수 있음

에러별로 나누기

try:
    a = [1,2]
    print(a[3])
    4/0
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")
except IndexError:
    print("인덱싱 할 수 없습니다.")
    
>>> 인덱싱 할 수 없습니다.

오류 회피하기

오류가 발생했을 때, 그냥 지나가라!

try:
    f = open("나없는파일", 'r')
except FileNotFoundError:
    pass

>>> 아무런 에러반응 없이 그냥 지나가짐

오류 일부러 발생시키기

프로그래머 입장에서 부모클래스를 쓰긴 쓰는데 이걸 변형해서 써라! 라고 강제를 하고 싶을 때 사용

class Bird:
    def fly(self):
        raise NotImplementedError

class Eagle(Bird):
    def fly(self):
        print("very fast")

eagle = Eagle()
eagle.fly()

>>> very fast
profile
사랑아 컴퓨터해 ~

0개의 댓글