| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- 스터디노트
- 재귀함수
- MacOS
- 등비수열
- DataFrame
- Folium
- Slicing
- 순열
- Machine Learning
- numpy
- plt
- tree.fit
- 머신러닝
- 조합
- 자료구조
- python
- 파이썬
- 통계학
- matplotlib
- pandas 메소드
- SQL
- pandas filter
- 기계학습
- 문제풀이
- barh
- maplotlib
- pandas
- INSERT
- 리스트
- 등차수열
Archives
- Today
- Total
코딩하는 타코야끼
[Python] 6강_객체지향 프로그 본문
728x90
반응형
1. 객체지향 프로그래밍 (Object Oriented Programming)
- 프로그램을 구성하는 변수와 함수를 서로 연관성있는 것 끼리 묶어서 모듈화하는 개발하는 언어들을 객체지향프로그래밍 언어라고 한다.
2. Instance(객체)
📍 정의
- 연관성 있는 값들과 그 값들을 처리하는 함수(메소드)들을 묶어서 가지고 있는 것(값).
- 객체의 구성요소
- 속성(Attribute)
- 객체의 데이터/상태로 객체를 구성하는 값들.
- 메소드(method)
- 객체가 제공하는 기능으로 주로 Attribute들을 처리한다.
- 속성(Attribute)
📍Class(클래스) 정의
- class란: 객체의 설계도
- 동일한 형태의 객체들이 가져야 하는 Attribute와 Method들을 정의 한 것
- 클래스를 정의할 때 어떤 속성과 메소드를 가지는지 먼저 설계해야 한다.
- 클래스로 부터 객체(instance)를 생성한 뒤 사용한다.
- 동일한 형태의 객체들이 가져야 하는 Attribute와 Method들을 정의 한 것

- 클래스 이름의 관례: 파스칼 표기법-각 단어의 첫글자는 대문자 나머진 소문자로 정의한다.
- ex) Person, Student, HighSchoolStudent
📍 클래스로부터 객체(Instance) 생성
- 클래스는 데이터 타입 instance는 값이다.

# 클래스 구현
class Person:
# 메소드들 구현
pass
📍 Attribute(속성)
- attribute는 객체의 데이터, 객체가 가지는 값, 객체의 상태
🌓 객체에 속성을 추가, 조회
- 객체의 속성 추가(값 변경)
- Initializer(생성자)를 통한 추가
- 객체.속성명 = 값 (추가/변경)
- 메소드를 통한 추가/변경
- 1(Initializer)은 초기화할 때. 2, 3은 속성값을 변경할 때 적용.
- 속성 값 조회
- 객체.속성명
- 객체.__dict__
- 객체가 가지고 있는 Attribute들을 dictionary로 반환한다.
# 객체 생성 p = Person() # 객체가 가진attribute 들을 조회 print(p.__dict__) >>> {}# attribute 추가 (2번 방식) p.name = '홍길동' # p.name -> p객체"의" name 변수 p.age = 30 p.address = "서울" print(p.__dict__) >>> {'name': '홍길동', 'age': 30, 'address': '서울'}
🌓 생성자(Initializer)
- 객체를 생성할 때 호출되는 특수메소드로 attribute들 초기화에 하는 코드를 구현한다.
- Inializer를 이용해 초기화하는 Attribute들이 그 클래스의 객체들이 가져야 하는 공통 Attribute가 된다.

구문)

class Person2:
# self는 이 메소드의 소유객체이다 / "__init__"인스텐스 변수를 초기화하기위해 만들어진다.
def __init__(self, name, age, address=None):
"""
Person 객체의 name, age, address 속성을 초기화.
"""
# 속성에 값 대입 - self.변수명 = 값
self.name = name
self.age = age
self.address = address
🌓 self parameter
- 메소드는 반드시 한개 이상의 parameter를 선언해야 하고 그 첫번째 parameter를 말한다.
- 메소드 호출시 그 메소드를 소유한 instance가 self parameter에 할당된다.
- Initializer의 self
- 현재 만들어 지고 있는 객체를 받는다.
- 메소드의 self
- 메소드를 소유한 객체를 받는다.
- Caller에서 생성자/메소드에 전달된 argument들을 받을 parameter는 두번째 변수부터 선언한다.
p = Person2('강호동', 30, '광주')
print(p.name, p.age, p.address)
>>>
강호동 30 광주
🌓 Instance 메소드(method)
- 객체가 제공하는 기능
- 객체의 attribute 값을 처리하는 기능을 구현한다.
구문)

🌓 self (첫번째 매개변수)
- 메소드를 소유한 객체를 받는 변수
- 호출할 때 전달하는 argument를 받는 매개변수는 두번째 부터 선언한다.

- 메소드 호출
- 객체.메소드이름([argument, ...])
class Person3:
def __init__(self, name, age, address=None):
self.name = name
self.age = age
self.address = address
def print_info(self): # argument가 없는 메소드
# attribute 들을 출력하는 메소드
print(f'이름: {self.name}, 나이: {self.age}, 주소 {self.address}')
def add_age(self, age):
# 나이에 전달받은 age를 더하는 메소드
self.age += age
# self.age = self.age + age
p2 = Person3("유관순", 20, "서울")
p2.print_info()
>>>
이름: 유관순, 나이: 20, 주소 서울
p2.add_age(2)
p2.print_info()
>>>
이름: 유관순, 나이: 22, 주소 서울
# p1의 이름 조회
print(p2.name)
# p1의 이름 변경
p2.name = ("리순신")
p2.print_info()
>>>
유관순
이름: 리순신, 나이: 22, 주소 서울
📍 정보 은닉 (Information Hiding)
- Attribute의 값을 caller(객체 외부)가 마음대로 바꾸지 못하게 하기 위해 직접 호출을 막고 setter/getter 메소드를 통해 값을 변경/조회 하도록 한다.
- 데이터 보호가 주목적이다.
- 변경 메소드에 Attribube 변경 조건을 넣어 업무 규칙에 맞는 값들만 변경되도록 처리한다.
- Attribute의 값을 변경하는 메소드. 관례상 set 으로 시작
- Attribute의 값을 조회하는 메소드. 관례상 get 으로 시작
🌓 Attribute 직접 호출 막기
- Attribute의 이름을 __(double underscore)로 시작한다. (__로 끝나면 안된다.)
- 같은 클래스에서는 선언한 이름으로 사용가능하지만 외부에서는 그 이름으로 호출할 수 없게 된다.
class Person4:
# name: 두글자 이상만 대입할 수 있다.
# age : 10이상만 대입 할 수 있다.
# address : 특별한 규칙이 없다.
# nage, age 는 아무값이나 대입할 수 없도록 처리 -> 정보은닉
def __init__(self, name, age, address):
self.__name = None
self.set_name(name) # 같은 클래스의 instance 메소드를 호출 -> self.메소드()
self.__age = None
self.set_age(age)
self.address = address
# 이름변경
def set_name(self, name):
if len(name) >= 2:
self.__name = name
# 이름조회
def get_name(self):
return self.__name
# 나이변경
def set_age(self, age):
if age >= 10:
self.__age = age
#나이조회
def get_age(self):
return self.__age
def print_info(self):
print(f'이름: {self.__name}, 나이: {self.__age}, 주소: {self.address}')
🌓 getter / setter
# 정보 은닉으로 값 변경 불가능.
p2 = Person4('김', 5, "인천")
p2.print_info()
>>>
이름: None, 나이: None, 주소: 인천
# setter로 값 변경 가능.
p2.set_name('홍길동')
p2.set_age(30)
p2.address = '부산'
p2.print_info()
>>>
이름: 홍길동, 나이: 30, 주소: 부산
🌓 property함수를 사용
- 은닉된 instance 변수의 값을 사용할 때 getter/setter대신 변수를 사용하는 방식으로 호출할 수 있도록 한다.
- 구현
- getter/setter 메소드를 만든다.
- 변수 = property(getter, setter) 를 등록한다.
- 호출
- 값조회: 변수를 사용 => getter가 호출 된다.
- 값변경: 변수 = 변경할 값 => setter가 호출 된다.
class Person5:
# name: 두글자 이상만 대입할 수 있다.
# age : 10이상만 대입 할 수 있다.
# address : 특별한 규칙이 없다.
# nage, age 는 아무값이나 대입할 수 없도록 처리 -> 정보은닉
def __init__(self, name, age, address):
self.__name = None
self.set_name(name) # 같은 클래스의 instance 메소드를 호출 -> self.메소드()
self.__age = None
self.set_age(age)
self.address = address
# 이름변경
def set_name(self, name):
if len(name) >= 2:
self.__name = name
# 이름조회
def get_name(self):
return self.__name
# 나이변경
def set_age(self, age):
if age >= 10:
self.__age = age
#나이조회
def get_age(self):
return self.__age
def print_info(self):
print(f'이름: {self.__name}, 나이: {self.__age}, 주소: {self.address}')
### property() 함수를 이용해서 getter/setter를 변수에 등록.변수를 이용해 getter /setter 를 호출할 수 있게 해준다.
name = property(get_name, set_name) # property(getter, setter)
age = property(get_age, set_age)
p.name = '이순신' # set_name()
p.age = 20 # set_age()
p.address = "부산" # address
print(p.name) # get_name()
print(p.age) # get_age()
print(p.address) # address
>>>
이순신
20
부산
🌓 데코레이터(decorator)를 이용해 property 지정.
- setter/getter 구현 + property()를 이용해 변수 등록 하는 것을 더 간단하게 구현하는 방식
- setter/getter 메소드이름을 변수처럼 지정. (보통은 같은 이름으로 지정)
- getter메소드: @property 데코레이터를 선언
- setter메소드: @getter메소드이름.setter 데코레이터를 선언.
- 반드시 getter 메소드를 먼저 정의한다.
- setter메소드 이름은 getter와 동일해야 한다.
- getter/setter의 이름을 Attribute 변수처럼 사용한다.
- 주의: getter/setter 메소드를 직접 호출 할 수 없다. 변수형식로만 호출가능하다.
class Person6:
def __init__(self, name, age, address=None):
self.name = name # setter name 메소드 호출
self.age = age # setter age 메소드 호출
self.address = address
@property
def name(self):
print('getter name')
return self.__name
@name.setter
def name(self,name):
print('setter name', name)
if len(name) >= 2:
self.__name = name
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if age >= 10:
self.__age = age
def print_info(self):
print(f'이름: {self.name}, 나이: {self.age}, 주소: {self.address}')
p = Person6('홍길동', 30, '서울')
p.print_info()
>>>
setter name 홍길동
getter name
이름: 홍길동, 나이: 30, 주소: 서울
📍 상속 (Inheritance)
- 기존 클래스를 확장하여 새로운 클래스를 구현한다.
- 생성된 객체(instance)가 기존 클래스에 정의된 Attribute나 method를 사용할 수있고 그 외의 추가적인 member들을 가질 수 있는 클래스를 구현하는 방법.
- 상위 클래스와 하위클래스는 계층관계를 이룬다.
🌓 기반(Base) 클래스, 상위(Super) 클래스, 부모(Parent) 클래스
- 물려 주는 클래스.
- 상속하는 클래스에 비해 더 추상적인 클래스가 된다.
- 상속하는 클래스의 데이터 타입이 된다.
🌓 파생(Derived) 클래스, 하위(Sub) 클래스, 자식(Child) 클래스
- 상속하는 클래스.
- 상속을 해준 클래스 보다 좀더 구체적인 클래스가 된다.
🌓 다중상속과 단일 상속
- 다중상속
- 여러 클래스로부터 상속할 수 있다
- 단일상속
- 하나의 클래스로 부터만 상속할 수 있다.
- 파이썬은 다중상속을 지원한다.
- MRO (Method Resolution Order)
- 다중상속시 메소드 호출할 때 그 메소드를 찾는 순서.
- 자기자신
- 상위클래스(하위에서 상위로 올라간다)
- 다중상속의 경우 먼저 선언한 클래스 부터 찾는다. (왼쪽->오른쪽)
- MRO 순서 조회
- Class이름.mro()
class Person:
def go(self):
print('학교에 간다.')
def eat(self):
print("점심을 먹는다.")
# Person을 상속받아서 Student/Teacher 클래스를 구현
class Student(Person): # 클래스르이름(상속할 클래스 이름.[, 상속할 클래스 이름,.....])
def study(self):
print("학생이 공부한다.")
class Teacher(Person):
def teach(self):
print("수업을 가르친다.")
class UniversityStudent(Student):
def drink(self):
print("술을 마신다.")
🌓 Method Overriding (메소드 재정의)
- 기반 클래스의 메소드의 구현부를 파생클래스에서 다시 구현하는 것을 말한다.기반 클래스는 모든 파생클래스들에 적용할 수 있는 추상적인 구현밖에는 못한다.이 경우 파생클래스에서 그 내용을 자신에 맞게 좀더 구체적으로 재구현할 수 있게 해주는 것을 Method Overriding이라고 한다.방법은 파생클래스에서 overriding할 메소드의 선언문은 그래로 사용하고 그 구현부는 재구현하면 된다.
🌓 super() 내장함수
- 파생 클래스에서 기반 클래스의 instance를 반환(return) 해주는 함수
- 구문

- 기반 클래스의 Instance 메소드를 호출할 때 – super().메소드()
- 특히 method overriding을 한 클래스에서 기반 클래스의 overriding한 메소드를 호출 할 경우 반드시 super().메소드() 형식으로 호출해야 한다.
- 같은 클래스의 Instance 메소드를 호출할 때 – self.메소드()
## 부모 클래스
class Person:
def __init__(self, name, age, address = None):
self.name = name
self.age = age
self.address = address
@property
def name(self):
return self.__name
@name.setter
def name(self,name):
if len(name) >= 2:
self.__name = name
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if age >= 10:
self.__age = age
#나이값을 더하는 메소드
def add_age(self, age):
self.age += age
# Person의 Attribute를(name, age, address)를 하나의 문자열로 만들어서 반환
def get_info(self):
return f'이름: {self.name}, 나이: {self.age}, 주소: {self.address}'
## 자식클래스
# Person 속성: name, age, address,
# Student 속성: grade(성적)
class Student(Person):
def __init__(self, name, age, address, grade):
#name, age, address는 부모객체에 초기화 -> Person클래스의 __init__()을 호출.
super().__init__(name, age, address) # 부모클래스의 __init__()메소드를 호출. - "super()"
self.grade = grade
#_______________________________________________________________________________ #
#get_info()메소드를 overriding -> grade 정보까지 추가
def get_info(self):
# name, age, address는 Person의 get_info()를 이용해서 조회
i = super().get_info()
return f'{i}, 성적: {self.grade}'
🌓 객체 관련 유용한 내장 함수, 특수 변수
- isinstance(객체, 클래스이름-datatype) : bool
- 객체가 두번째 매개변수로 지정한 클래스의 타입이면 True, 아니면 False 반환
- 여러개의 타입여부를 확인할 경우 class이름(type)들을 리스트로 묶어 준다.
- 기반클래스는 파생클래스객체의 타입이 되므로 객체와 그 객체의 기반클래스 비교시 True가 나온다.
- 객체.__dict__
- 객체가 가지고 있는 Attribute 변수들과 대입된 값을 dictionary에 넣어 반환
- 객체.__class__
- 객체의 타입을 반환
isinstance(p, Person)
isinstance('abc', Person)
isinstance(s, Student)
#객체(값)의 타입 -> 생성한 클래스, 생성한 클래스의 상위클래스
# s(Student객체)의 타입 : Sturdent, Person
>>>
True
-------------------------
isinstance(10,int)
print(type(10))
type(10) ==int, isinstance(10,int)
>>>
<class 'int'>
(True, True)
📍 특수 메소드
🌓 특수 메소드란
- 특정한 상황에서 사용될 때 자동으로 호출되도록 파이썬 실행환경에 정의된 약속된 메소드들이다. 객체에 특정 기능들을 추가할 때 사용한다.
- 정의한 메소드와 그것을 호출하는 함수가 다르다.
- ex) __init__() => 객체 생성할 때 호출 된다.
- 정의한 메소드와 그것을 호출하는 함수가 다르다.
- 메소드 명이 더블 언더스코어로 시작하고 끝난다.
- ex) __init__(), __str__()
- 매직 메소드(Magic Method), 던더(DUNDER) 메소드라고도 한다.
- 특수메소드 종류
🌓 주요 특수메소드
- __init__(self [, …])
- Initializer
- 객체 생성시 호출 된다.
- 객체 생성시 Attribute의 값들을 초기화하는 것을 구현한다.
- self 변수로 받은 instance에 Attribute를 설정한다.
- __call__(self, […])
- 객체를 함수처럼 호출 할 면 실행되는 메소드
- Argument를 받을 Parameter 변수는 self 변수 다음에 필요한대로 선언한다.
- 처리결과를 반환할 경우 return value 구문을 넣는다. (필수는 아니다.)
- __repr__(self)
- Instance(객체) 자체를 표현할 수 있는 문자열을 반환한다.
- 보통 객체 생성하는 구문을 문자열로 반환한다.
- 반환된 문자열을 eval() 에 넣으면 동일한 attribute값들을 가진 객체를 생성할 수 있도록 정의한다.
- 내장함수 repr(객체) 호출할 때 이 메소드가 호출 된다.
- 대화형 IDE(REPL) 에서 객체를 참조하는 변수 출력할 때도 호출된다.
- eval(문자열)실행 가능한 구문의 문자열을 받아서 실행한다.
- Instance(객체) 자체를 표현할 수 있는 문자열을 반환한다.
- __str__(self)
- Instance(객체)의 Attribute들을 묶어서 문자열로 반환한다.
- 내장 함수 str(객체) 호출할 때 이 메소드가 호출 된다.
- str() 호출할 때 객체에 __str__()의 정의 안되 있으면 __repr__() 을 호출한다. __repr__()도 없으면 상위클래스에 정의된 __str__()을 호출한다.
- print() 함수는 값을 문자열로 변환해서 출력한다. 이때 그 값을 str() 에 넣어 문자열로 변환한다.
class Plus:
def __init__(self, num1, num2):
# 덧셈할때 사용할 피연산자 두개를 속성으로 저장.
self.num1 = num1
self.num2 = num2
def __call__(self, n):
#객체의 메인 기능(동작)을 구현하는 메소드 -> 객체를 함수처럼 사용할 수 있도록 한다.
return (self.num1 +self.num2)**n
# def calc(self):
# return self.num1 + self.num2
class Person: ###부모 클래스
def __init__(self, name, age, address = None):
self.name = name
self.age = age
self.address = address
@property
def name(self):
return self.__name
@name.setter
def name(self,name):
if len(name) >= 2:
self.__name = name
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if age >= 10:
self.__age = age
#나이값을 더하는 메소드
def add_age(self, age):
self.age += age
#특수메소드 정의
def __repr__(self):
return f"Person('{self.name}', {self.age}, '{self.address}')" # 객체에 무엇이 들어있는지
def __str__(self):
return f'이름: {self.name}, 나이: {self.age}, 주소: {self.address}' #객체의 상세내용
# 연산자 재정의 특수메소드
# 덧셈
def __add__(self, other):
# other 가 숫자이면 self.age에 더한다.
# other 가 다른 Person객체이면 그 객체의 age에 self의 age를 더한다.
# p + 30 (self:p, other:30)
if isinstance(other, (int,float)):
return self.age + other
elif isinstance(other, Person):
return self.age + other.age
def __gt__(self, other):
#self 객체와 other 객체의 나이를 비교
if isinstance(other, Person):
return self.age > other.age
else:
raise TypeError(f'Person과 {type(other)}는 비교할 수 없습니다') #Exception을 발생시킨다.
📍 연산자 재정의(Operator overriding) 관련 특수 메소드
- 연산자의 피연산자로 객체를 사용하면 호출되는 메소드들
- 다항연산자일 경우 가장 왼쪽의 객체에 정의된 메소드가 호출된다.
- a + b 일경우 a의 __add__() 가 호출된다.
🌓 비교 연산자
- __eq__(self, other) : self == other
- == 로 객체의 내용을 비교할 때 정의 한다.
- __lt__(self, other) : self < other, gt(self, other): self > other
- min()이나 max()에서 인수로 사용할 경우 정의해야 한다.
- __le__(self, other): self <= other
- __ge__(self, other): self >= other
- __ne__(self, other): self != other
🌓 산술 연산자
- __add__(self, other): self + other
- __sub__(self, other): self - other
- __mul__(self, other): self * other
- __truediv__(self, other): self / other
- __floordiv__(self, other): self // other
- __mod__(self, other): self % other
3. class변수, class 메소드
📍 class변수
- (Intance가 아닌) 클래스 자체의 데이터
- Attribute가 객체별로 생성된다면, class변수는 클래스당 하나가 생성된다.
- 구현
- class 블럭에 변수 선언.
📍 class 메소드
- 클래스 변수를 처리하는 메소드
- 구현
- @classmethod 데코레이터를 붙인다.
- 첫번째 매개변수로 클래스를 받는 변수를 선언한다. 이 변수를 이용해 클래스 변수나 다른 클래스 메소드를 호출 한다.
4. static 메소드
📍 정의
- 클래스의 메소드로 클래스 변수와 상관없는 단순기능을 정의한다.
- Caller 에서 받은 argument만 가지고 일하는 메소드를 구현한다.
- 구현
- @staticmethod 데코레이터를 붙인다.
- Parameter에 대한 규칙은 없이 필요한 변수들만 선언한다.
📍 class 메소드/변수, static 메소드 호출
- 클래스이름.변수
- 클래스이름.메소드()
class Calculator:
PI = 3.14 #클래스 변수
@classmethod
def circle_area(clazz, radius):
return radius * radius * clazz.PI #클래스 변수 호출.
@staticmethod # 함수로 사용하기엔 거의 사용 안함
def square_area(width, height):
return width * height
****
# 클래스 변수 호출: 클래스이름.변수명
print(Calculator.PI)
>>>
3.14
반응형
'[T.I.L] : Today I Learned > Python' 카테고리의 다른 글
| [Python] 8강_예외처리 (0) | 2023.04.09 |
|---|---|
| [Python] 7강_패키지 모듈 import (0) | 2023.04.05 |
| [Python] 5강_함수 (0) | 2023.04.04 |
| [Python] 4강_제어문, 컴프리헨션 (0) | 2023.04.04 |
| [Python] 3강_자료구조 (0) | 2023.04.04 |