class Page: # 클래스 정의
def __init__(self, num, content):
self.num = num # ページ番号
self.content = content # 페이지 내용
def output(self):
return f'{self.content}'
Page # 클래스 객체 Page가 정의됨
__main__.Page
# 인스턴스화
title_page = Page(0, 'Python Practice Book')
type(title_page) # 인스턴스의 클래스를 확인함
__main__.Page
# Page 클래스의 인스턴스인지 확인함
isinstance(title_page, Page)
True
# 인스턴스가 가진 속성을 확인함
dir(title_page)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'content', 'num', 'output']
title_page.output() # 인스턴스 메서드 호출
'Python Practice Book'
class Klass:
def some_method(self): # 인스턴스 메서드 정의
print('method')
def some_function(self): # 같은 인수의 함수 정의
print('function')
# 함수는 function 클래스의 인스턴스임
type(some_function)
function
# 인스턴스 메서드도 function 클래스의 인스턴스
type(Klass.some_method)
function
# 인스턴스를 통해 접근하면 method 클래스가 됨
kls = Klass()
type(kls.some_method)
method
# 클래스 객체의 속성에 함수를 추가
Klass.some_function = some_function
# 인스턴스 메서드로 실행
kls.some_function()
function
title_page.section = 0
title_page.section
0
first_page = Page(1, 'first page')
first_page.section
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-16-622c9b4a10cc> in <module> 1 first_page = Page(1, 'first page') ----> 2 first_page.section AttributeError: 'Page' object has no attribute 'section'
# 클래스 정의
class Page:
def __init__(self, num, content, section=None):
self.num = num
self.content = content
self.section = section
def output(self):
return f'{self.content}'
# 인스턴스 작성
title_page = Page(0, 'Python Practice Book')
title_page.section # section은 None
title_page.output()
'Python Practice Book'
# section을 지정해 다른 인스턴스를 작성
first_page = Page(1, 'first page', 1)
first_page.section # section이 지정되어 있음
1
first_page.output()
'first page'
class Klass:
def __new__(cls, *args): # 컨스트럭터
print(f'{cls=}')
print('new', args)
# 작성한 인스터스를 반환함
return super().__new__(cls)
def __init__(self, *args): # 이니셜라이저
# 인스턴스 초기화는 여기에서 수행함
print('init', args)
# 인스턴스화
kls = Klass(1, 2, 3)
cls=<class '__main__.Klass'> new (1, 2, 3) init (1, 2, 3)
class Evil:
def __new__(cls, *args):
return 1
# Evil 클래스 인스턴스화
evil = Evil()
isinstance(evil, Evil)
False
type(evil)
int
# 인스턴스는 __new__()의 반환값
evil
1
class MyClass(Evil):
def print_class(self):
print('MyClass')
my = MyClass() # my 값은 1이 됨
# 추가되었어야 할 메서드를 이용할 수 없음
my.print_class()
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-33-5c63bdce6f16> in <module> 1 # 추가되었어야 할 메서드를 이용할 수 없음 ----> 2 my.print_class() AttributeError: 'int' object has no attribute 'print_class'
my
1
class Book:
def __init__(self, raw_price):
if raw_price < 0:
raise ValueError('price must be positive')
self.raw_price = raw_price
self._discounts = 0
@property
def discounts(self):
return self._discounts
@discounts.setter
def discounts(self, value):
if value < 0 or 100 < value:
raise ValueError(
'discounts must be between 0 and 100')
self._discounts = value
@property
def price(self):
multi = 100 - self._discounts
return int(self.raw_price * multi / 100)
book = Book(2000)
book.discounts # 초기 할인율 0
0
book.price # 초기 가격 2000
2000
book.discounts = 20 # 할인율 설정
book.price # 할인 후의 가격
1600
book.discounts = 120 # 할인율이 100을 초과하면 에러 발생
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-39-4bc99df62c28> in <module> ----> 1 book.discounts = 120 # 할인율이 100을 초과하면 에러 발생 <ipython-input-35-553c66fea917> in discounts(self, value) 11 def discounts(self, value): 12 if value < 0 or 100 < value: ---> 13 raise ValueError( 14 'discounts must be between 0 and 100') 15 self._discounts = value ValueError: discounts must be between 0 and 100
book.discounts = -20
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-40-1a951ff04058> in <module> ----> 1 book.discounts = -20 <ipython-input-35-553c66fea917> in discounts(self, value) 11 def discounts(self, value): 12 if value < 0 or 100 < value: ---> 13 raise ValueError( 14 'discounts must be between 0 and 100') 15 self._discounts = value ValueError: discounts must be between 0 and 100
book.price = 1000
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-41-cd29227d939f> in <module> ----> 1 book.price = 1000 AttributeError: can't set attribute
book._discounts # _로 시작하는 변수도 참조할 수 있음
20
class Klass:
def __init__(self, x):
self.__x = x
kls = Klass(10)
kls.__x # 이 이름으로는 참조할 수 없음
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-44-0c02c06d28bb> in <module> 1 kls = Klass(10) ----> 2 kls.__x # 이 이름으로는 참조할 수 없음 AttributeError: 'Klass' object has no attribute '__x'
kls._Klass__x # 변환 규칙을 알고 있다면 참조할 수 있음
10
# 클래스 변수를 가진 클래스 정의
class Page:
book_title = 'Python Practice Book'
Page.book_title # 인스턴스가 없어도 참조할 수 있음
'Python Practice Book'
Page.book_title = 'No title' # 클래스 변수 업데이트
Page.book_title
'No title'
first_page = Page()
second_page = Page()
# 클래스 변수는 인스턴스에서도 참조 가능
first_page.book_title
'No title'
second_page.book_title
'No title'
# 클래스 변수 업데이트
Page.book_title = 'Python Practice Book'
# 클래스 변수는 모든 인스턴스에서 공유됨
first_page.book_title
'Python Practice Book'
second_page.book_title
'Python Practice Book'
# 아래는 인스턴스 변수가 됨
first_page.book_title = '[Draft]Python Practice Book'
first_page.book_title
'[Draft]Python Practice Book'
# 클래스 변수는 변경되지 않음
Page.book_title
'Python Practice Book'
first_page.book_title # 인스턴스 변수
'[Draft]Python Practice Book'
# 인스턴스 변수 삭제
del first_page.book_title
# 인스턴스 속성이 아니므로, 클래스 속성이 검색됨
first_page.book_title
'Python Practice Book'
# 속성을 이용한 정렬에 사용할 수 있는 표준 라이브러리를 임포트
from operator import attrgetter
class Page:
book_title = 'Python Practice Book'
def __init__(self, num, content):
self.num = num
self.content = content
def output(self):
return f'{self.content}'
# 클래스 메서드의 첫 번째 인수는 클래스 객체
@classmethod
def print_pages(cls, *pages):
# 클래스 객체 이용
print(cls.book_title)
pages = list(pages)
# 페이지 순으로 정렬해서 출력
for page in sorted(pages, key=attrgetter('num')):
print(page.output())
first = Page(1, 'first page')
second = Page(2, 'second page')
third = Page(3, 'third page')
# 클래스 메서드 호출
Page.print_pages(first, third, second)
Python Practice Book first page second page third page
# 인스턴스에서도 호출할 수 있음
first.print_pages(first, third, second)
Python Practice Book first page second page third page
class Page:
def __init__(self, num, content):
self.num = num
self.content = content
@staticmethod # 스태틱 메서드로 정의
def check_blank(page):
return bool(page.content)
page = Page(1, '')
Page.check_blank(page)
False
def check_blank(page): # 함수로 문제 없음
return bool(page.content)
check_blank(page)
False
class Page:
def __init__(self, num, content):
self.num = num
self.content = content
def output(self):
return f'{self.content}'
# 메서드 오버라이드
class TitlePage(Page):
def output(self):
# 베이스 클래스의 메서드는 자동으로 호출되지 않으므로
# 명시적으로 호출함
title = super().output()
return title.upper()
title = TitlePage(0, 'Python Practice Book')
title.output()
'PYTHON PRACTICE BOOK'
class Length(float): # 내장 타입의 서브 클래스 작성
def to_cm(self):
return super().__str__() + 'cm'
pencil_length = Length(16)
print(pencil_length.to_cm())
16.0cm
class HTMLPageMixin:
def to_html(self):
return f'<html><body>{self.output()}</body></html>'
# 다중 상속을 사용한 Mixin 이용
class WebPage(Page, HTMLPageMixin):
pass
page = WebPage(0, 'web content')
page.to_html()
'<html><body>web content</body></html>'
class A:
def hello(self):
print('Hello')
class B(A):
def hello(self):
print('Hola')
super().hello() # 베이스 클래스의 메서드를 실행
class C(A):
def hello(self):
print('안녕하세요')
super().hello() # 베이스 클래스의 메서드를 실행
class D(B, C):
def hello(self):
print('Xin Chao')
super().hello() # 베이스 클래스의 메서드를 실행
d = D()
d.hello()
Xin Chao Hola 안녕하세요 Hello
D.__mro__ # 메서드 결정 순서 확인
(__main__.D, __main__.B, __main__.C, __main__.A, object)
d.hello()
Xin Chao Hola 안녕하세요 Hello