숫자에서 함수까지 파이썬의 모든 것은 객체이다. 하지만 파이썬은 특수 구문을 사용해서 대부분의 객체를 숨긴다.
「객체」
- 데이터(변수, 속성)와 코드(함수, 메서드)를 포함하는 커스텀 자료구조이다. 객체는 어떤 구체적인 것의 인스턴스를 나타낸다. 객체를 명사로, 메서드를 동사로 생각하면 된다. 객체는 개별 사물을 나타내며 해당 메서드는 다른 사물로 상호작용하는 방법을 정의한다.
「객체 선언하기」
- 먼저 클래스를 정의한다
class Car():
pass
- 클래스 이름을 호출해서 클래스로부터 객체를 생성할 수 있다.
a_car=Car()
another_car=Car()
「속성」
- 속성은 클래스나 객체 내부의 변수이다. 객체나 클래스가 생성되는 동안이나 이후에 속성을 할당할 수 있다. 그리고 속성은 다른 객체일 수 있다.
class Car():
pass
a_car=Car()
another_car=Car()
print(a_car)
print(another_car)
->
<__main__.Car object at 0x0000022CCE38F520>
<__main__.Car object at 0x0000022CCE38F4F0>
> 간단한 객체에도 여러 속성을 저장하는데 사용할 수 있다. 리스트나 딕셔너리와 같은 자료구조를 사용하는 대신 여러 객체를 사용하여 다른 값을 저장할 수 있다.
- 속성을 이야기하면 일반적으로 객체속성을 의미한다. 하지만 클래스 속성도 존재한다.
「메서드」
- 메서드는 클래스 또는 객체의 함수이다. 다른 함수와 비슷하지만 특별한 방식으로 사용 가능하다
「메서드 초기화」
class Car():
def __init__(self, code):
self.code=code
avante=Car('DN7')
print('last avnate code: ',avante.code )
->last avnate code: DN7
- Car 클래스의 정의를 찾는다
- 메모리에 새 객체를 초기화(생성)한다
- 객체의 __init__메서드를 호출한다. 새롭게 생성된 객체를 self에 전달하고, 인수(DN7)를 code에 전달한다
- 객체에 code값을 저장한다
- 새 객체를 반환한다
- avante 변수에 이 객체를 연결한다
> 하나의 클래스에서 많은 객체를 개별적으로 만들 수 있다. 그러나 파이썬은 데이터를 객체로 구현하므로 클래스 자체가 객체이다. 프로그램에서는 한 클래스의 객체만 존재한다
「상속」
-기존 클래스에서 일부를 추가ㅏ거나 변경하여 새 클래스를 생성한다. 코드를 재사용하는 방법이며, 상속을 이용하면 새로운 클래스는 기존 클래스를 복사하지 않고 기존 클래스의 모든 코드를 사용할 수 있다.
「부모 클래스 상속」
- 필요한 것만 추가하거나 변경해서 새 클래스를 정의한다. 그리고 기존 클래스의 행동을 오버라이드(재정의)한다. 기존 클래스는 부모, 슈퍼, 베이스 클래스라고 부르며, 새 클래스는 자식, 서브 , 파생된 클래스라고 부른다.
class Hyundai():
def exclaim(self):
print('i am parent company')
class Kia():
pass
avante=Hyundai()
canival=Kia()
avante.exclaim()
carnival.exclaim()
「메서드 오버라이드」
class Hyundai():
def exclaim(self):
print('i am parent company')
class Kia():
def exclaim(self):
print('i am son company')
DN7=Hyundai()
EV9=Kia()
class genesis():
def __init__(self,code):
self.code=code
class sedan(genesis):
def __init__(self, code):
self.code="g70"+code
class suv(genesis):
def __init__(self, code):
self.code=code+"gv70"
g80=genesis('premium')
gv90=suv('premium')
g90=sedan('premium')
- 두 클래스 객체를 생성한다
- 각 객체의 exclaim()메서드를 호출한다
- exclaim() 메서드를 오버라이드 했고, __init__() 메서드를 포함한 모든 메서드를 오버라이드 할 수 있다
- __init__() 초기화 메서드는 부모클래스와 같은 인수를 취하지만 객체의 인스턴스 내부에서는 다른 값을 저장한다.
「super() 부모에게 도움받기」
- 자식클래스에서 부모 클래스를 호출하고 싶으면 super() 메서드를 사용하면 된다.
class stock():
def __init__(name, code):
name.code=code
class stockOption():
def __init__(name,code, start):
super().__init__(name)
code.stockOption=stockOption
> 자식클래스에서 __init__()메서드를__init__() 메서드를 정의하면 부모 클래스의 __init__() 메서드를 대체하는 것이므로 더 이상 자동으로 부모 클래스의 __init__() 메서드가 호출되지 않는다. 그래서 명시적으로 호출해야 한다.
- super() 메서드는 부모 클래스의 정의를 얻는다
- __init__() 메서드는 stock.__init__() 메서드를 호출한다. 이 메서드는 name 인수를 슈퍼 클래스로 전달하는 역할을 한다. 그러므로 슈퍼 클래스에 선택적 인수를 제공하기만 하면 된다.
- code.stockOption=stockOption은 stockOption클래스를 stock 클래스와 다르게 만들어 주는 코드이다
> 자식 클래스가 자신의 방식으로 무언가를 처리하지만, 여전히 부모클래스로부터 무언가가 필요할 때 super() 메서드를 사용한다.
「다중상속」
- 파이썬의 상속은 메서드 해석순서(method resolution order)MRO에 달려있다.
> 각 파이썬 클래스에는 특수 메서드 MRO가 있다. 이 메서드는 해당 클래스 객체에 대한 메서드 또는 속성을 찾는데 필요한 클래스의 리스트를 반환한다. __mro__라는 유사한 속성은 해당 클래스의 튜플이며 먼저 선언된 부모 클래스를 상속받는다
class Car:
def engine(self):
return 'movis'
class Tire(Car):
def tires(self):
return 'hangook'
class Motor(Car):
def eletric(self):
return 'lg eletric'
class module(Tire,Motor):
pass
class factory(Tire,Motor):
pass
> module 클래스에서 메서드나 속성을 찾는 순서
- 객체 자신(module 타입)
- 객체의 클래서(module)
- 클래스의 첫번째 부모 클래스(Motor)
- 클래스의 두번째 부모 클래스(Tire)
- 부모의 부모클래스 (Car)
「믹스인」
- 클래스 정의에 부모 클래스를 추가하여 상속받을 수 있다. 하지만 헬퍼의 목적으로만 사용할 수 있다. 다른 상위 클래스와 메서드를 공유하지 않으면, 메서드 해석 순서의 모호성을 피한다. 이러한 부모 클래스를 믹스인(mixin)이라고 하며 로깅과 같은 사이드 작업에서 이를 사용할 수 있다.
class Car():
def engine(self):
import pprint
pprint.pprint(vars(self))
class Automo(Car):
pass
A=Automo()
A.name="Hyundai motor"
A.feature="metal"
A.number="005380"
A.dump()
「Self」
- 파이썬에서 공백 사용 외에 어떤 한 비판은 인스턴스메서드의 첫 번째 인수로 self를 포함해야 한다. 파이썬은 적절한 객체의 속성과 메서드를 찾기 위해 self 인수를 사용한다.
「속성접근」
- 파이썬을 일반적으로 객체 속성과 메서드는 공개되어 있어, 스스로 잘 관리해야 한다.
> 개발자는 속성 값을 직접 가져와서 설정 할 수 있다. 그리고 실수로 인해서 수정하지 못하도록 속성에 대한 접근 프라이버시를 얻을 수도 있다.
「Getter/Setter」
- 객체지향언어에서는 외부로부터 바로 접근할 수 없는 private객체를 지원하며 개발지는 private속성의 값을 읽고 쓰기 위해 getter/setter 메서드를 사용한다.
> 파이썬에서는 private 속성이 없지만 조금의 프라이버시를 얻기 위해서 애매한 속성 이름을 가진 getter/setter 메서드를 작성할 수 있다.
- 속성 프라이버시를 위해서 프로퍼티(property)를 사용할 수 있다.
「메서드 타입」
> 메서드는 클래스의 일부이며, 어떤 메서드는 해당 클래스에서 작성된 객체의 일부이다. 어떤 메서드는 두 사항에 어느 것도 해당하지 않는다
- 메서드 앞에 데커레이터가 없다면 이것은 인스턴스 메서드이다. 첫 번째 인수는 객체 자신을 참조하는 self이다
- 메서드 앞에 @classmethod 데커레이터가 있다면 클래스 메서드이다. 첫번째 인수는 cls이며 클래스 자체를 참조한다
- 메서드 앞에 @staticmethod 데커레이터가 있다면 정적 메서드이다. 첫번째 인수는 자신의 객체나 클래스가 아니다.
「인스턴스 메서드」
- 클래스 정의에서 메서드의 첫번째 인수가 self라면 이 메서드는 인스턴스 메서드이다. 이것이 일반적인 클래스를 생성할 때의 메서드 타입이다.
> 인스턴스 메서드의 첫 번째 매개변수는 self이고, 파이썬은 이 메서드를 호출할 때 객체를 전달한다.
「클래스 메서드」
- 클래스 메서드는 클래스 전체에 영향을 미친다. 클래스에 대한 어떤 변화는 모든 객체에 영향을 미친다.
> 클래스 정의에서 함수에 @classmethod 데커레이터가 있다면 클래스 메서드이며 이 메서드의 첫 번째 매개변수는 클래스 자신이다. 파이썬에서는 보통 이 클래스의 매개변수를 cls로 사용한다.
class A():
count=0
def __init__(self):
A.count+=1
def exclaim(self):
print('A')
@classmethod
def kid(cls):
print('a has',cls.count,'some objects')
「정적 메서드」
- 정적 메서드는 클래스나 객체에 영항을 미치지 못한다. 이 메서드는 편의를 위해서 존재한다.
> 정적 메서드는 @staticmethod 데커레이터가 있고 첫 번째 매개변수로 cls나 self가 없다.
class A():
@staticmethod
def A():
print('A')
「덕 타이핑」
- 파이썬은 다형성을 느슨하게 구현했고, 이는 클래스에 상관없이 같은 동작을 다른 객체에 적용할 수 있게 됐다.
class Quote():
def __init__(self, person, words):
self.person=person
self.words=words
def who(self):
return self.person
def says(self):
return self.words+'.'
class QuestionQuote(Quote):
def says(self):
return self.words+'?'
class ExclamationQuote(Quote):
def says(self):
return self.words+'!'
- who() 메서드는 저장된 person 문자열의 값을 반환한다
- says() 메서드는 특정 구두점과 함께 저장된 words 문자열을 반환한다
> Question와 ExclamationQuote 클래스에서 초기화 함수를 사용하지 않았다. 그러므로 부모의 __init__() 메서드를 오버라이드하지 않는다.
> 파이썬은 자동으로 부모클래스 메서드를 호출해서 인스턴스 변수에 저장한다. 그러므로 자식 클래스에서 생성된 객체에 접근할 수 있다.
「매직 메서드 종류」
- 비교연산을 위한 매직 메서드
메서드 | 설명 |
__eq__(self,other) | self == other |
__ne__(self,other) | self != other |
__lt__(self,other) | self < other |
__gt__(self,other) | self >other |
__le__(self,other) | self <= other |
__ge__(self,other) | self >= other |
- 산술연산을 위한 메서드
메서드 | 설명 |
__add__(self,other) | self + other |
__sub__(self,other) | self - other |
__mul__(self,other)- | self * other |
__floordiv__(self,other) | self // other |
__truediv__(self,other) | self / other |
__mod__(self,other) | self % other |
__pow__(self,other) | self ** other |
- 기타 메서드
메서드 | 설명 |
__str__(self) | str(self) |
__repr__(self) | repr(self) |
__len__(self) | len(self) |
「객체의 사용」
- 비슷한 행동을 하지만 내부 속성이 다른 개별 인스턴스가 필요할 때, 객체는 유용하다
- 클래스는 상속을 지원하지만, 모듈을 상속을 지원하지 않는다
- 어떤 한가지 일만 수행한다면 모듈이 가장 좋은 선택이다. 파이썬은 모듈이 참조된 횟수에 상관없이 단 하나의 복사본만 불러온다
- 여러 함수로 인해 전달하는 변수가 있다면 클래스를 정의하는 것이 좋다.
- 가장 간단한 문제 해결법을 사용한다.