dict(note=1, notebook=2, sketchbook=3)
{'note': 1, 'notebook': 2, 'sketchbook': 3}
items = {'note':1, 'notebook':2, 'sketchbook':3 }
items['book'] = 4
del items['note'] # dict() 객체에서 제외 : 별로 출력은 없음
items.pop('notebook') # dict() 객체에서 제외 : 해당 value 를 출력
2
print(items)
items.get('note', "None Existed") # .get() : key의 값을 호출, 없으면 뒤의 값 출력
{'sketchbook': 3, 'book': 4}
'None Existed'
# .update(dict()) : dict() 객체 합치는 메서드
items_two = {'notes':10}
items.update(items_two)
items
{'sketchbook': 3, 'book': 4, 'notes': 10}
'book' in items
True
'note' not in items
True
items = {'note', 'notebook', 'sketchbook'}
items.add('book')
items
{'book', 'note', 'notebook', 'sketchbook'}
items.pop() # 순서와 Key 가 별도로 없음
'sketchbook'
items
{'book', 'note', 'notebook'}
def increment(page_number, last):
r"""page_number + 1 값이 last 값을 넘어가는지 확인"""
next_page = page_number + 1
if next_page <= last:
return next_page
raise ValueError('Invalid arguments')
increment(2, 10)
3
이름이 없는 함수
increment = lambda num: num+1
print(increment)
increment(3)
<function <lambda> at 0x7f2f087f64c0>
4
nums = ['one', 'two', 'three']
filtered = filter(lambda x : len(x) == 3, nums)
list(filtered)
['one', 'two']
# Check if given numbers are in range using lambda function
test = lambda x : True if (x > 10 and x < 20) else False
print(test(3))
print(test(12))
print(test(24))
# https://thispointer.com/python-how-to-use-if-else-elif-in-lambda-functions/
# https://stackoverflow.com/questions/60261960/how-to-use-lambda-if-else-in-map-on-list-in-python
list(map(lambda x : 'ok' if x == "apple" else None, ['apple', 'banana', 'cherry']))
False True False
['ok', None, None]
# (p127) Optional : None 의 가능성이 있을 때 사용한다
from typing import Optional
def incerment(
page_num: int,
last: int, *,
ignore_error: bool = False) -> Optional[int]:
next_page = page_num + 1
if next_page <= last:
return next_page
if ignore_error:
return None
raise ValueError('Invalid arguments')
incerment.__annotations__
# increment(1, 3, ignore_error=1)
{'page_num': int, 'last': int, 'ignore_error': bool, 'return': typing.Union[int, NoneType]}
def decrement(page_number:int) -> int:
previous_page: int
previous_page = page_number - 1
return previous_page
decrement(2)
1
def increment(
page_number: int,
last:int,
*,
ignore_error: bool = False) -> Optional[int]:
next_page = page_number + 1
if next_page <= last:
return next_page
if ignore_error:
return None
raise ValueError("Invalid arguments")
increment(1, 10, ignore_error=1)
2
# 클래스 객체 만들기
class Page:
def __init__(self, number, content):
self.number = number
self.content = content
def output(self):
return f'{self.content}'
Page
__main__.Page
# 클래스 인스턴스 만들기
title_page = Page(0, 'Python Practice Book')
type(title_page)
__main__.Page
# 클래스 객체의 인스턴스 동일성 확인
isinstance(title_page, Page)
True
" , ".join(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 , number , output'
title_page.output()
'Python Practice Book'
__NEW__
의 cls
: (p 138)cls
를 클래스 메서드(Class Method) 라고 한다__INIT__
: 이니셜라이저 는 인스턴스__new__
출력값은 __init__
의 첫번째 인수 self
로 전달 받는다class Klass:
# new 의 첫번째 인수 : 클래스의 Method
# @classmethod 대신 __new__ 를 적용
def __new__(cls, *args):
r"""cls : 클래스"""
print(f"{cls=}")
print('new', args)
data = 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 파라미터 __init__ 전달 (`__new__` -> `__init__`)
# Class parametor => `cls` 로 __new__ => `self` 로 __init__ 전달
# 1) Key 를 지정 안한 경우 : 순차적 Key 값을 적용
# 2) Key 를 지정한 경우 : Key 에 맞게 대입된다
class Craft:
def __new__(cls, *args, **kwargs):
print ("Creating Instance")
return super().__new__(cls) # instance
def __init__(self, a, b):
self.a = a
self.b = b
i = Craft(2, 3)
print(i.a, i.b)
i = Craft(a=1, b=2)
print(i.a, i.b)
Creating Instance 2 3 Creating Instance 1 2
# __new__() 사용시 주의할 점
# :: 인스턴스 생성시 값을 출력한다
class Evil:
def __new__(cls, *args):
return 1
evil = Evil()
isinstance(evil, Evil)
False
다른 변수의 값 을 Class 인스턴스 에서 활용하는 용도로 사용한다 (Setter 와 Getter 개념의 이해)
class Book:
def __init__(self, raw_price):
if raw_price < 0:
raise ValueError('price must be positive')
self.raw_price = raw_price
self._discount_value = 0 # 초깃값
@property
def discount(self):
return self._discount_value
@discount.setter
def discount(self, value):
if value < 0 or 100 < value:
raise ValueError(
'discounts must be between 0 and 100')
self._discount_value = value
@property
def price(self):
multiple = 100 - self._discount_value
return int(self.raw_price * multiple / 100)
book = Book(2000)
book.price, book.discount
(2000, 0)
book.discount = 20
book.price
1600
변수이름 앞
_
는 외부에 공개할 필요 없는 프라이빗 변수이나, 약속에 불과 해서 외부서 참조가능
하지만, 변수이름 앞
__
두개는 클래스 이름을 덧붙인 변수 즉_클래스명__변수명
으로 자동 변환된다
class Klass:
def __init__(self, x):
self.__x = x
kls = Klass(10)
try:
kls.__x
except Exception as e:
import termcolor # termcolor.COLORS
print(termcolor.colored(e, 'red'))
kls._Klass__x
'Klass' object has no attribute '__x'
10
# 부모 클래스의 인스턴스 에서는 동일하게 보인다..
class test:
def instance_add(self, a, b):
return a + b
@staticmethod # 정적 메서드는 self 불필요
def static_add(a, b):
return a - b
@classmethod # 클래스 메서드는 cls 를 첫번째 인자로 사용
def class_add(cls, a, b):
return a * b
a = test
print(a.instance_add(None, 4, 4)) # 원본 함수의 내용
print(test.static_add(4, 4)) # 정적메서드 내용
print(test.class_add(4, 4)) # 클래스메서드 내용
8 0 16
## 하지만 이를 상속한 자식 클래스에서는 차이가 발생한다
# 클래스 메소드 : cls로 `현재 자기가 실행된 클래스 속성` 을 가져온다
# 정적 메소드 : 부모 클래스(Windows)의 속성을 가져온다
class Windows:
os = "window10" # 클래스 속성
def __init__(self):
self.out = "OS: " + self.os
def os_output(self):
print(self.out)
@staticmethod # 부모원본
def static_os():
return Windows()
@classmethod # 자식의 변경내용
def class_os(cls):
return cls()
class Linux(Windows):
os = "Linux" # 클래스 속성
Linux.static_os().os_output() # 부모의 원본을 호출
Linux.class_os().os_output() # 자식의 변경된 내용을 호출
OS: window10 OS: Linux
@classmethod
)¶@classmethod 클래스에 속한 메서드로, 첫번째 인수에 클래스 객체를 전달 합니다
cls
이름을 사용from operator import attrgetter
class Page:
book_title = 'Python Practice Book :: ======'
def __init__(self, number, content):
self.number = number
self.content = content
def output(self):
return f'{self.content}'
@classmethod
def print_pages(cls, *pages):
print(cls.book_title)
pages = list(pages)
# key=attrgetter('number') : sorted() 함수의 정렬기준
for page in sorted(pages, key=attrgetter('number')):
print(page.output())
first = Page(1, 'first page')
second = Page(20, 'second book page')
third = Page(3, 'third page')
first
<__main__.Page at 0x7f2f08797e80>
# 클래스를 활용한 호출
Page.print_pages(first, second, third)
Python Practice Book :: ====== first page third page second book page
# 인스턴스 객체를 활용한 호출
first.print_pages(first, second, third)
Python Practice Book :: ====== first page third page second book page
from operator import attrgetter
class Page:
book_title = 'Python Practice Book :: ======'
def __init__(self, number, content):
self.number = number
self.content = content
def output(self):
return f'{self.content}'
@classmethod
def print_pages(cls, *pages):
print(cls.book_title)
pages = list(pages)
# key=attrgetter('number') : sorted() 함수의 정렬기준
for page in sorted(pages, key=attrgetter('number')):
print(page.output())
first = Page(1, 'first page')
second = Page(20, 'second book page')
third = Page(3, 'third page')
first
<__main__.Page at 0x7f2f087aa3d0>
# 클래스를 활용한 호출
Page.print_pages(first, second, third)
Python Practice Book :: ====== first page third page second book page
# 인스턴스 객체를 활용한 호출
first.print_pages(first, second, third)
Python Practice Book :: ====== first page third page second book page
first.content
'first page'
@staticmethod
)¶class Page:
def __init__(self, number, content):
self.number = number
self.content = content
@staticmethod
def check_blank(page):
return bool(page.content)
page = Page(1, '')
Page.check_blank(page)
False
class Inheritance
Child Class
에서 Base Class
가 갖는 Method 를 그래도 사용하면서 변수등을 추가한다__str__
와 같은 내장 타입은 사용자 클래스도 동일하게 서브 클래스로 정의된다class Page:
def __init__(self, number, content):
self.number = number
self.content = content
def output(self):
return f'{self.content}'
# Method Override : Page 클래스를 통으로 상속
class TitlePage(Page):
def output(self):
title = super().output()
return title.upper()
title = TitlePage(0, 'Python Practice Book')
print(title.output())
title.number, title.content
PYTHON PRACTICE BOOK
(0, 'Python Practice Book')
class Length(float):
def to_cm(self):
return super().__str__() + ' cm'
def to_inch(self):
return super().__str__() + ' inch'
pencil_length = Length(16)
pencil_length.to_cm(), pencil_length.to_inch()
('16.0 cm', '16.0 inch')
Multiple Inheritance
self
는 원본 클래스의 요소와 메서드 를 연결해야, 자식클래스가 잘 작동한다,
로 여러개를 구분한다# 부모 클래스1
class Page:
def __init__(self, number, content):
self.number = number
self.content = content
def output(self):
return f'{self.content}'
# 부모 클래스
class HTMLPageMixin:
def to_html(self):
return f'<html><body>{self.output()}</body></html>'
class WebPage(Page, HTMLPageMixin):
pass
page = WebPage(0, 'web content')
page.to_html()
'<html><body>web content</body></html>'
def counter():
count = 0
def _increase():
nonlocal count
count += 1
return count
return _increase
counter1 = counter()
counter1, counter1(), counter1()
(<function __main__.counter.<locals>._increase()>, 1, 2)