
Notion에서 정리한 내용을 공유용으로 옮긴 내용입니다.
양식과 구성의 어색함이 있을 수 있습니다.
04/07(월) ~ 04/08(화) 학습내용을 바탕으로 업로드하였음
하루 밀려서 오늘 싹 정리...
이 부분 너무 어려워...나 울어...
기존에 문제 풀 때도 헤맸던...영상을 따로 찾아보고 했었는데 또 배워도 모르네
객체 지향 프로그래밍이란?
객체의 배경
(방식의 발전?)
변수에서 시작 (v1, v2, v3...)
배열/리스트/튜플 (묶어서 [v1, v2, v3...] 한번에 관리)
딕셔너리
딕셔너리에서 객체로
객체란?
개발자는 class 설계
이거 가지고 객체 만들어줘 요청하면 class 개수만큼의 객체 생성
학생 100개 만들어줘 100번 요청한다면 → 객체 100개
객체를 아무리 많이 만들어도 변수만 만들어지기 때문에 메모리를 많이 먹지 않음
시작이다
class TestClass1 :
pass
# 객체를 생성한다.
t1 = TestClass1()
t2 = TestClass1()
print(t1)
print(t2)
<main.TestClass1 object at 0x0000016871104EC0>
<main.TestClass1 object at 0x0000016871104680>
# 비교
t3 = t2
print(t2)
print(t3)
<main.TestClass1 object at 0x0000016871104680>
<main.TestClass1 object at 0x0000016871104680>
→ t2, t3는 같은 객체
# 파이썬은 생성한 객체에 변수를 추가하는 것이 가능하다.
t1.a1 = 100
print(t1.a1)
100
# 객체에 변수를 추가한다고 하더라도 같은 클래스를 가지고 만든 다른 객체에는 추가되지 않는다.
# 객체는 독립적이기 때문이다.
print(t2.a1)
# 에러!
~~# 파이썬은 클래스를 통해 생성되는 객체의 멤버 변수를 정의할 수 없다. 헷갈려서 수정~~
# 파이썬은 클래스 정의 부분에 멤버 변수를 미리 선언하지 않는다.
# 클래스를 통해 객체를 생성하면 아무것도 가지고 있지 않는 텅 비어있는 객체가 생성된다.
# 이 객체에 변수를 추가해 줘야 한다.
class TestClass2 :
# 생성자
# self : 생성된 객체의 정보가 담기고 이를 통해 객체에 접근할 수 있다.
def __init__(self) :
print('init')
print(f'self : {self}')
# 객체가 가지고 있어야 할 변수를 여기에서 추가해준다.
self.a1 = 100
self.a2 = 200
클래스를 통해 객체를 생성할 때 자동으로 호출되는 함수(메서드)
파이썬에서는 클래스를 통해 객체를 생성할 경우 텅 비어있는 객체를 생성하고 생성자를 호출한다.
여기에서 객체에 변수를 추가하는 작업을 하면 클래스를 통해 만들어지는 모든 객체는 동일한 이름의 변수들을 가진 상태에서 사용할 수 있다.
t1과 self의 주소값 같음
t1 = TestClass2() # 객체 생성 : 텅 빈 객체 생성 # -> 무조건 자동으로 __init__ 호출
# 객체의 주소값이 매개변수인 self 로 들어옴
print(f't1 : {t1}')
init
self : <__main__.TestClass2 object at 0x00000168713D40B0>
t1 : <__main__.TestClass2 object at 0x00000168713D40B0>
t1 = TestClass2()
print(f't1 : {t1}')
# 객체가 가지고 있는 변수에 접근한다.
print(f't1.a1 : {t1.a1}')
print(f't1.a2 : {t1.a2}')
init
self : <__main__.TestClass2 object at 0x00000168711048C0>
t1 : <__main__.TestClass2 object at 0x00000168711048C0>
t1.a1 : 100
t1.a2 : 200
t2 = TestClass2()
print(f't2 : {t2}')
print(f't2.a1 : {t2.a1}')
print(f't2.a2 : {t2.a2}')
init
self : <__main__.TestClass2 object at 0x00000168713D4AD0>
t2 : <__main__.TestClass2 object at 0x00000168713D4AD0>
t2.a1 : 100
t2.a2 : 200
t1 실행시 self와 t1의 주소값, t2 실행시 self와 t2의 주소값 각각 같음
그러나 t1과 t2의 self의 주소값은 서로 다름 (독립적)
파이썬은 클래스 정의시 멤버 변수를 필수로 선언하지 않기 때문에,
__init__이 없는 경우 클래스를 통해 객체를 생성하면 아무 멤버도 없는 텅 빈 객체가 생성됨
# (학습) 텅 빈 객체 만들어짐
class TestClass5:
pass
t = TestClass5()
print(t.__dict__) #객체 t가 가진 멤버 변수들을 딕셔너리 형태로 보여줘.
{}
따라서 생성자를 이용해 객체가 생성될 때 객체 내부에 변수를 추가하는 작업을 함
class TestClass2 :
def __init__(self) :
print('init')
print(f'self : {self}')
self.a1 = 100
self.a2 = 200
이러한 class가 있으면 객체 생성시 a1, a2라는 멤버 변수를 가진 상태로 생성됨
(’a1’ : 100, ‘a2’ : 200)
t1 = TestClass2()
print(f't1 : {t1}')
실행하면 파이썬이 TestClass2()를 호출하면서 init(self) 함수도 자동으로 호출
생성된 객체의 주소값을 self 자리에 넣음 (init(t1)이 실행되는 것. 일종의 t1 = self 가 됨)
만약 새 객체 t2를 생성한다면, t2의 주소값과 그때 print(f'self : {self}')되는 self의 주소값도 같을 것
색깔 넣었다!!! 어휴 내가 파이썬하니 HTML하니
# 같은 클래스로 생성한 객체라고 하더라도 서로 독립적이므로
# 변수의 값이 항상 같지는 않다.
t1.a1 = 1000
print(f't1.a1 : {t1.a1}')
print(f't2.a1 : {t2.a1}')
→ t1.a1 : 1000
t2.a1 : 100
# 생성자도 함수의 일종이므로 매개변수를 가질 수 있다.
# 단, 첫 번째 매개변수에는 생성된 객체의 주소 값으로 결정되기 때문에
# 두 번째 매개변수부터 값을 결정해 주면 된다. (기본값도 설정할 수 있다.)
class TestClass3 :
# 생성자
def __init__(self, v1, v2, v3 = 3) :
self.a1 = v1
self.a2 = v2
self.a3 = v3
t1 = TestClass3(10, 20, 30)
print(t1.a1, t1.a2, t1.a3)
t2 = TestClass3(10, 20)
print(t2.a1, t2.a2, t2.a3)
→ 10 20 30
10 20 3
# 객체를 통해 호출하기 때문에 첫 번째 매개변수에는 객체의 주소값이 들어온다.
# 이를 통해 객체에 접근하여 객체가 가지고 있는 변수를 사용할 수 있다.
class TestClass4 :
# 생성자
def __init__(self, a1, a2) :
self.v1 = a1
self.v2 = a2
# 메서드
# 객체를 통해서 메서드를 호출하면 첫 번째 매개변수에 메서드를 호출하기 위해
# 사용한 객체의 주소값이 들어온다.
# 이를 통해 객체에 접근하여 객체의 변수를 사용할 수 있다.
def test_method(self) :
print(self.v1)
print(self.v2)
t1 = TestClass4(10, 20)
t1.test_method()
t2 = TestClass4(100, 200)
t2.test_method()
→ 10
20
100
200
class TestClass4 :
def __init__(self, a1, a2) :
self.v1 = a1
self.v2 = a2 위와 같은 클래스 호출할 때t1 = TestClass4(10, 20) 클래스 호출 → __init__이라는 생성자를 호출 self : 이 객체 자신 ( t1 )TestClass4.__init__(t1, 10, 20) 그래서 마치 이렇게 t1이라는 객체가 자동으로 self 자리에 들어가고 10, 20이 a1, a2로 들어가는 것처럼 동작각각의 특성을 알아보면
→ 동물 class 새로 생성
클래스가 다른 클래스가 가진 것들을 물려받는 개념
상속 시켜 주는 클래스 : 부모 클래스
상속 받는 클래스 : 자식 클래스
자식 클래스는 부모가 가진 것들을 마치 자기 자신한테 있는 것 처럼 사용할 수 있다.
부모 클래스
class Animal :
def __init__(self, _type) :
self.animal_type = _type
def eat(self) :
print(f'{self.animal_type}가 사료를 먹습니다')
class Dog(Animal) :
def speaking(self) :
print('멍멍')
class Cat(Animal) :
def speaking(self) :
print('냐옹 냐옹')
Animal이 변수 자리에
t1 = Dog('강아지')
print(t1.animal_type)
t1.eat()
t1.speaking()
t2 = Cat('고양이')
t2.eat()
t2.speaking()
강아지
강아지가 사료를 먹습니다
멍멍
고양이가 사료를 먹습니다
냐옹 냐옹
울음소리는 다르지만 먹는 것은 같으므로 애니멀 클래스(부모 클래스)에서 상속
ex) 키보드 입력받는 것 → 문자열로 받음
대응방법
발생되는 데이터에 대해서 문제가 있는 데이터를 동작시키기 전에 if 문으로 미리 검사
→ 문제가 있으면 return 등을 통해서 돌아가지 않도록 만들기
오류 발생시
- 정상화
- 오류 기록 후 종료
- 만약 어디까지 했는지 기록하지 않으면 처음부터 해야 함
이런저런 오류들
test 1)

ZeroDivisionError : 파이썬에서 만들어 목록화해놓은 일종의 “Class”
a1 = 10 / 0
print(a1)
print('이 부분이 수행될까요?')

→ 10 / 0 에서 중단
아래 수행은 되지 않음
try:
a1 = 10 / 0
print(a1)
except :
print('오류가 발생하였습니다')
print('이 부분이 수행될까요?')
오류가 발생하였습니다
이 부분이 수행될까요?
잘 수행됨
try :
a1 = 10 + 20
print(a1)
except :
print('예외가 발생하였습니다')
else :
print('예외가 발생하지 않았습니다')
finally :
print('무조건 동작하는 부분입니다')
30
예외가 발생하지 않았습니다
무조건 동작하는 부분입니다
try → else → finally 동작
try :
a1 = 10 / 0
print(a1)
except :
print('예외가 발생하였습니다')
else :
print('예외가 발생하지 않았습니다')
finally :
print('무조건 동작하는 부분입니다')
예외가 발생하였습니다
무조건 동작하는 부분입니다
try → except → finally 동작
오류는 하나만 발생한다.
오류 클래스
# 모듈
- 파이썬 코드를 작성하는 파일의 확장자는 py이다.
- 이 py 파일이 하나의 모듈이 된다.
- 파이썬 코드를 작성할 때 다른 py 파일에 작성되어 있는 것을
사용할 수 있다.
# test_module1.py
print('test_module.py')
print('안녕하세요')
# test_module1.py 파일의 코드를 "실행"시킨다.
# (다른 언어와 다른 부분)
import test_module1
test_module.py
안녕하세요
import test_module1
→ 출력 아무것도 안 됨
# <test_modul2.py>
test2 = 100
def test2_function() :
print('test2_function')
class TestClass2 :
pass
import test_module2
print(test_module2.test2)
test_module2.test2_function()
t2 = test_module2.TestClass2()
print(t2)
100
test2_function
<test_module2.TestClass2 object at 0x000001BDEC44FBF0>
# <test_module3.py>
test3 = 300
def test3_function() :
print('test3_function')
class TestClass3 :
pass
# 별칭
# 모듈명이 너무 길다고 생각되면 별칭을 사용할 수 있다.
import test_module3 as m3
print(m3.test3)
m3.test3_function()
t3 = m3.TestClass3()
print(t3)
300
test3_function
<test_module3.TestClass3 object at 0x000001BDEC55AC60>
print(test_module3.test3)
→ NameError
# <test_module4.py>
test4 = 400
def test4_function() :
print('test4_function')
class TestClass4 :
pass
# 모듈명 생략 - 사용하고 싶은 것에 대해서만 지정하기
# from 모듈명 import 함수명,변수명,클래스명등
from test_module4 import test4
from test_module4 import test4_function, TestClass4
print(test4)
test4_function()
t4 = TestClass4()
print(t4)
400
test4_function
<test_module4.TestClass4 object at 0x000001BDEB92AF60>
# <test_module5.py>
test5 = 500
def test5_function() :
print('test5_function')
class TestClass5 :
pass
# 모듈에 있는 모든 요소들을 모듈명 생략하겠다라고 한다.
from test_module5 import *
print(test5)
test5_function()
t5 = TestClass5()
print(t5)
500
test5_function
<test_module5.TestClass5 object at 0x000001BDEA31C560>
# <test_module6.py>
test6 = 600
def test6_function() :
print('test6_function')
class TestClass6 :
pass
# 패키지 내의 모듈을 import 한다.
import package1.test_module6
# 패키지 내의 모듈이 가지고 있는 요소를 사용할 때는 패키지명.모듈명을 해야 한다.
print(package1.test_module6.test6)
package1.test_module6.test6_function()
t6 = package1.test_module6.TestClass6()
print(t6)
600
test6_function
<package1.test_module6.TestClass6 object at 0x000001F6A6AD2600>
# <test_module7.py>
test7 = 700
def test7_function() :
print('test7_function')
class TestClass7 :
pass
# 패키지명을 생략하고 싶다면
# 모듈명은 명시해야 한다.
from package2 import test_module7
print(test_module7.test7)
test_module7.test7_function()
t7 = test_module7.TestClass7()
print(t7)
700
test7_function
<package2.test_module7.TestClass7 object at 0x000001F6A7FF7B30>
# <test_module8.py>
test8 = 800
def test8_function() :
print('test8_function')
class TestClass8 :
pass
# 패키지명과 모듈명을 생략한다.
from package3.test_module8 import test8, test8_function, TestClass8
print(test8)
test8_function()
t8 = TestClass8()
print(t8)
800
test8_function
<package3.test_module8.TestClass8 object at 0x000001F6A7FA79B0>
__init__ .py 파일에 있는 __all__ 변수에 담긴 리스트를 확인__init__ .py 파일이 있는 폴더만 패키지로 인식을 하였으나버전이 업데이트 되면서 py만 있으면 패키지로 인식__init__ .py 파일을 만들고 __all__ 변수에 모듈명이나 하위 패키지명을 문자열로 넣어 줘야 함__init__ .py 없을 때from package4 import *
print(test_module9.test9)
print(test_module10.test10)
→ NameError
__init__ .py 파일 생성# * 를 통해 패키지명을 생략하고 사용할 수 있도록 허용해주고 싶은 모듈이나 하위 패키지명을
# 리스트에 문자열로 작성해준다.
__all__ = ['test_module9', 'test_module10']<test_module9.py>
test9 = 900
def test9_function() :
print('test9_function')
class TestClass9 :
pass<test_module10.py>
test10 = 1000
def test10_function() :
print('test10_function')
class TestClass10 :
passfrom package4 import *
print(test_module9.test9)
print(test_module10.test10)
900
1000
진짜 끝
노션에서는 토글로 접어서 내보냈는데 다 들어갔네...
오래 전부터 필기에서 초록색으로 내 생각, 모르겠는 부분, 사족 적는 데 쓰는데
객체지향 부분 노션 페이지는 진짜 한 20~30%가 초록색ㅋㅋㅋ
이제 이해될 거 같긴 한데 또 실전 만나면 모르겠네
일단은 GPT가 많이 발전해서 다행이라는 생각만 드는 중
와 5시! 디코에 아무도 없음 당연하지
노는 시간이 길어서 늦어졌지만 어쨌든 마무리