클래스
클래스 구조 만들기
객체에 숫자 지정할 수 있게 만들기
'''
Created on 2018. 9. 14.
@author: kitcoop
'''
# 함수(function)
def func1():
print('func1() 호출')
def func2(first):
print('func2() 호출 : {0}'.format(first))
class FourCal :
# 메서드
def cfunc1(self):
print('cfunc1() 호출')
# self = this
print(self)
def cfunc2(self, first):
print('cfunc2() 호출 : {0}'.format(first))
a = FourCal()
print(type(a))
func1()
a.cfunc1()
func2(10)
a.cfunc2(20)
java와 비교해보면 self 는 this이다.
class FourCal :
# 클래스 변수
# java에서 static
# 멤버 변수
# java에서 멤버 변수로 접근하려면 this.멤버변수로 접근했다
# 메서드
def cfunc1(self):
# 멤버변수 선언
self.data1 = 1
print(self.data1)
fc = FourCal()
fc.cfunc1()
class FourCal :
# 클래스 변수
# java에서 static
# 멤버 변수
# java에서 멤버 변수로 접근하려면 this.멤버변수로 접근했다
# 메서드
def cfunc1(self):
# 멤버변수 선언
self.data1 = 1
print(self.data1)
def cfunc2(self):
print(self.data1)
fc = FourCal()
fc.cfunc1()
fc.cfunc2()
위와 같은 식이면 cfunc2()는 멤버변수라면 값이 불러와지고 지역변수라면 안될 것이다 근데 결과는 1이 출력되었기때문에 멤버변수임을 알 수 있다. 허나 fc.cfunc1()가 실행되지 않으면 에러가 난다.
class FourCal :
# 클래스 변수
# java에서 static
# 멤버 변수
# java에서 멤버 변수로 접근하려면 this.멤버변수로 접근했다
# 메서드
def cfunc1(self):
# 멤버변수 선언
self.data1 = 1
print(self.data1)
def cfunc2(self):
print(self.data1)
fc = FourCal()
# fc.cfunc1()
fc.cfunc2()
더하기 기능 만들기
class FourCal():
def setdata(self, first, second):
self.first = first
self.second = second
def sum(self):
result = self.first + self.second
return result
a = FourCal()
a.setdata(4, 2)
print(a.sum())
class FourCal():
def setdata(self, first, second):
self.first = first
self.second = second
def sum(self):
result = self.first + self.second
return result
a = FourCal()
# a.setdata(4, 2)
FourCal.setdata(a, 4, 2)
print(a.sum())
eval() - 실행 함수로 해보자
class FourCal():
def setdata(self, first, second):
self.first = first
self.second = second
def sum(self):
result = self.first + self.second
return result
a = FourCal()
# a.setdata(4, 2)
# FourCal.setdata(a, 4, 2)
eval('FourCal.setdata(a, 4, 2)')
print(a.sum())
지금까지 사용한 소스에서 setdata, getdata등은 setter, getter등으로 기존 프로그래머들이 사용하였기 때문에 비슷하게 구현해 준 것이다.
생성자 (Constructor) - 생성자는 초기화를 자동으로 하는 특성을 가지고 있다.
class FourCal():
def __init__(self):
self.first = 10
self.second = 20
def setdata(self, first, second):
self.first = first
self.second = second
def sum(self):
result = self.first + self.second
return result
a = FourCal()
# a.setdata(4, 2)
# FourCal.setdata(a, 4, 2)
# eval('FourCal.setdata(a, 4, 2)')
print(a.sum())
오버로딩은 아래와 같이 사용하는 방법이 있다.
class FourCal():
# def __init__(self, first):
# self.first = 10
# self.second = 20
def __init__(self, first, second):
self.first = first
self.second = second
def setdata(self, first, second):
self.first = first
self.second = second
def sum(self):
result = self.first + self.second
return result
a = FourCal(100, 200)
# a.setdata(4, 2)
# FourCal.setdata(a, 4, 2)
# eval('FourCal.setdata(a, 4, 2)')
print(a.sum())
클래스 변수
class Family:
lastname = "김"
# 인스턴스화 과정이 없다.
print(Family.lastname)
# 인스턴스화 과정을 거쳐보자
a = Family()
b = Family()
print(a.lastname)
print(b.lastname)
위치를 확인해 보자 - id() 사용
class Family:
lastname = "김"
# 인스턴스화 과정이 없다.
print(Family.lastname)
# 인스턴스화 과정을 거쳐보자
a = Family()
b = Family()
print(a.lastname)
print(b.lastname)
print(id(Family.lastname))
print(id(a.lastname))
print(id(b.lastname))
같은 값("김")을 가져오므로 주소값이 같다.
클래스의 상속
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 sum(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 MoreFourCal(FourCal):
def pow(self):
result = self.first ** self.second
return result
mfc = MoreFourCal(4, 2)
print(mfc.sum())
print(mfc.pow())
메서드 오버라이딩 - 덮어쓰기
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 sum(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 MoreFourCal(FourCal):
def pow(self):
result = self.first ** self.second
return result
fc = FourCal(4, 0)
print(fc.div())
위와 같이 실행하면 에러가 발생하였다. 0을 나눌 수 없기 때문이다.
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 sum(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 MoreFourCal(FourCal):
def pow(self):
result = self.first ** self.second
return result
class SafeFourCal(FourCal):
def div(self):
if self.second == 0:
return 0
else:
return self.first / self.second
# mfc = MoreFourCal(4, 2)
# print(mfc.sum())
# print(mfc.pow())
# fc = FourCal(4, 0)
# print(fc.div())
sfc = SafeFourCal(4, 0)
print(sfc.div())
클래스의 활용
결국 메소드로 처리하는것보단 클래스로 처리하는게 낫다라는 이야기
예외 처리
오류는 어떤 때 발생하는가?
자바와 같이 try catch를 사용한 것을 try except 구문을 사용한다
오류 예외 처리 기법
try, except 문
a = 4
b = 0
print(a / b)
a = 4
b = 0
# print(a / b)
print('시작')
try:
print(a / b)
except ZeroDivisionError as e:
print(e)
print('끝')
정상일 경우
a = 4
b = 1
# print(a / b)
print('시작')
try:
print(a / b)
except ZeroDivisionError as e:
print(e)
print('끝')
try .. else
print('시작')
try :
f = open('foo.txt', 'r')
except FileNotFoundError as e:
print(str(e))
else:
data = f.read()
f.close()
print('끝')
foo라는 파일이 있으면 foo파일 안에 적혀있는 데이터를 읽어온다.
print('시작')
try :
f = open('foo.txt', 'r')
except FileNotFoundError as e:
print(str(e))
else:
data = f.read()
print(data)
f.close()
print('끝')
ex05.py를 읽어오고 싶었는데 인코딩이 안맞아서 에러가 났다. 인코딩을 맞춰주고 출력이 되게끔 해보자
import codecs
print('시작')
try :
# utf-8을 읽을 때
f = codecs.open('ex05.py', 'r', 'utf-8')
except FileNotFoundError as e:
print(str(e))
else:
data = f.read()
print(data)
f.close()
print('끝')
codec이라는 것을 import 시키고 f = codecs.open이라고 한뒤 반드시 utf-8로 설정해줘야 한다.
try .. finally - 무조건 수행
여러개의 오류처리하기
try:
a = [1, 2]
print(a[3])
# 4/0
except ZeroDivisionError as e:
print(e)
except IndexError as e:
print(e)
try:
a = [1, 2]
# print(a[3])
4/0
except ZeroDivisionError as e:
print(e)
except IndexError as e:
print(e)
try:
a = [1, 2]
print(a[3])
4/0
# except ZeroDivisionError as e:
# print(e)
# except IndexError as e:
# print(e)
except (ZeroDivisionError, IndexError) as e:
print(e)
오류 회피하기
오류 일부러 발생시키기 - raise
예외 만들기 - 예외 클래스를 상속받아서 예외 발생
class MyError(Exception):
pass
def say_nick(nick):
if nick == '바보':
raise MyError()
print(nick)
say_nick('천사')
say_nick('바보')
class MyError(Exception):
pass
def say_nick(nick):
if nick == '바보':
raise MyError()
print(nick)
try:
say_nick('천사')
say_nick('바보')
except MyError:
print('허용되지 않는 별명입니다.')
class MyError(Exception):
pass
def say_nick(nick):
if nick == '바보':
raise MyError()
print(nick)
try:
say_nick('천사')
say_nick('바보')
except MyError as e:
# print('허용되지 않는 별명입니다.')
print(e)
class MyError(Exception):
def __str__(self):
return '허용되지 않는 별명입니다.'
def say_nick(nick):
if nick == '바보':
raise MyError()
print(nick)
try:
say_nick('천사')
say_nick('바보')
except MyError as e:
# print('허용되지 않는 별명입니다.')
print(e)
class MyError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
def say_nick(nick):
if nick == '바보':
raise MyError('허용되지 않는 별명입니다.')
print(nick)
try:
say_nick('천사')
say_nick('바보')
except MyError as e:
# print('허용되지 않는 별명입니다.')
print(e)
에러 발생 시점에 오류메시지를 전달받았다.
모듈 - 라이브러리
모듈이란 함수나 변수 또는 클래스 들을 모아 놓은 파일이다. 모듈은 다른 파이썬 프로그램에서 불러와 사용할수 있게끔 만들어진 파이썬 파일이라고도 할 수 있다. 우리는 파이썬으로 프로그래밍을 할 때 굉장히 많은 모듈을 사용한다. 다른 사람들이 이미 만들어 놓은 모듈을 사용할 수도 있고 우리가 직접 만들어서 사용할 수도 있다. 여기서는 모듈을 어떻게 만들고 사용할 수 있는지 알아보겠다.
위 표시한 부분이 모듈(라이브러리)의 경로이다.
단순히 클래스라고 이름 짓는것이 아니라 모듈이라고 짓는다. 자바에서는 클래스는 하나의 파일이지만 파이선의 클래스는 더 다양한 요소들을 포함할 수 있기 때문에 자바 보다 큰 개념이다.
모듈 만들고 불러 보기
Ex03.mod1
def sum(a, b):
return a + b
Ex03.exec1
# 파일명 = 모듈
import mod1
# 모듈 -> 클래스, 함수
print(mod1.sum(3, 4))
Ex03.mod1
def sum(a, b):
return a + b
def safe_sum(a, b):
if type(a) != type(b):
print('더할수 있는 것이 아닙니다.')
return
else:
result = sum(a, b)
return result
Ex03.exec1
# 파일명 = 모듈
import mod1
# 모듈 -> 클래스, 함수
print(mod1.sum(10, 20))
print(mod1.safe_sum(3, 4))
Ex03.mod1
def sum(a, b):
return a + b
def safe_sum(a, b):
if type(a) != type(b):
print('더할수 있는 것이 아닙니다.')
return
else:
result = sum(a, b)
return result
Ex03.exec2
from mod1 import sum, safe_sum
print(sum(10, 20))
print(safe_sum(20, 10))
if __name__ == "__main__": 의 의미
Ex03.mod1
def sum(a, b):
return a + b
def safe_sum(a, b):
if type(a) != type(b):
print('더할수 있는 것이 아닙니다.')
return
else:
result = sum(a, b)
return result
print(safe_sum('a', 1))
print(safe_sum(1, 4))
print(sum(10, 10.4))
Ex03.exec3
import mod1
위와 같이 했을때 모듈로서의 기능이 없는데 왜 굳이 이렇게 할까 의문이 들 것이다.
Ex03.mod1
def sum(a, b):
return a + b
def safe_sum(a, b):
if type(a) != type(b):
print('더할수 있는 것이 아닙니다.')
return
else:
result = sum(a, b)
return result
# main 함수(public static void main)
if __name__ == '__main__':
print(safe_sum('a', 1))
print(safe_sum(1, 4))
print(sum(10, 10.4))
Ex03.exec3
import mod1
디버깅을 할 때 사용하는 용도로 많이 쓴다.
클래스나 변수 등을 포함한 모듈
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(2))
print(sum(PI, 4.4))
위는 템플릿이다. - Module:Main을 클릭해보자
위와 같이 메인이 자동적으로 생성되서 제공된다.
새 파일 안에서 이전에 만든 모듈 불러오기
import sys print(sys.path) sys.path.append("C:/Python/module") print(sys.path)
['C:\\Python\\eclipse-workspace\\Ex03', 'C:\\Python\\eclipse-workspace\\Ex03', 'C:\\Python\\Python36\\DLLs', 'C:\\Python\\Python36\\lib', 'C:\\Python\\Python36', 'C:\\Python\\Python36\\lib\\site-packages', 'C:\\Python\\Python36\\python36.zip']
['C:\\Python\\eclipse-workspace\\Ex03', 'C:\\Python\\eclipse-workspace\\Ex03', 'C:\\Python\\Python36\\DLLs', 'C:\\Python\\Python36\\lib', 'C:\\Python\\Python36', 'C:\\Python\\Python36\\lib\\site-packages', 'C:\\Python\\Python36\\python36.zip', 'C:/Python/module']
import sys
print(sys.path)
sys.path.append("C:/Python/module")
print(sys.path)
import mod2
print(mod2.sum(3, 4))
동적 로딩으로 인해 module 디렉토리의 mod2를 불러와서 해당 구문을 실행할 수 있다.
위와 같은 방법은 이클립스를 사용하지 않을 때 사용한다.
댓글