๐ ํด๋น ํฌ์คํ ์ ์ธํ๋ฐ์ ํ์ด์ฌ ์ค๊ธ ๊ฐ์๋ฅผ ๊ณต๋ถํ๋ฉด์ ๋ณต์ต์ฐจ์์ผ๋ก ์ ๋ฆฌํ ํฌ์คํ ์ ๋๋ค. ํด๋น ๋ด์ฉ์ ์ฃผ๋ก ๋ณธ์ธ์ ๋ณต์ต์ฉ์ด๋ผ์ ์์ธํ ์ค๋ช ์ ์๋ ์ ์ํด ๋ถํ๋๋ฆฌ๊ฒ ์ต๋๋ค. ์๋ณธ ์ฝ๋๋ ์ฌ๊ธฐ์ ์์ต๋๋ค.
์ด๋ฒ ํฌ์คํ ์ ์ง๋ ํฌ์คํ ์์ ์ ๊น ์ดํด๋ณด์๋ Magic method(๋งค์ง ๋ฉ์๋)์ ๋ํด ์์๋ณด๊ณ ์ค์ต ์์ ๋ก ๊ตฌํํด๋ณด์. ๋ํ Tuple ์ฑ์ง์ ์ง๋์ง๋ง ๋ง์น ํ์ด์ฌ ์๋ฃ๊ตฌ์กฐ ์ค ํ๋์ธ Dictionary ์ฒ๋ผ Key, Value๋ฅผ ๊ฐ๋ Named Tuple์ ๋ํด ์์๋ณด๊ณ ๊ฐ๋จํ ์ค์ต์ผ๋ก ๊ตฌํํด๋ณด์.
์ฐ์ Special method ๋ผ๊ณ ๋ ๋ถ๋ฆฌ์ฐ๋ ๋งค์ง ๋ฉ์๋๋ ์ด๋ฏธ ๋ด์ฅ๋์ด(built-in) ๋ง๋ค์ด์ง ๋ฉ์๋๋ฅผ ์๋ฏธํ๋ค. ์ฆ, ๋ค์ ์ฝ๋์ ๊ฐ์ด int ํ๋ ํ๋์ ํด๋์ค์ด๋ฉฐ ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ๊ฐ์ง ๋ด์ฅ๋ ๋งค์ง ๋ฉ์๋๋ฅผ ๊ฐ๊ณ ์๋ค.
# int๋ ํ๋์ Class๋ก ์ ์๋์ด ์๋ค!
print(int)
print('-'*50)
# dir ๋ฉ์๋๋ฅผ ํตํด ๋งค์ง ๋ฉ์๋ ํ์ธํด๋ณด๊ธฐ
print(dir(int))
์ ๊ฒฐ๊ณผํ๋ฉด์์ __add__ ๋ ์ฐ๋ฆฌ๊ฐ ํํ ์ฌ์ฉํ๋ '+' ๋ผ๋ ์ฐ์ฐ์ ์๋ฏธํ๋ค. ์ฆ ๋ค๋ฅธ ์ฐ์ฐ -, *, / ์ฐ์ฐ๋ค๋ ์ด๋ฐ ๋ด์ฅ๋ ๋งค์ง ๋ฉ์๋๋ก ์ด๋ฏธ ๊ตฌํ๋์ด ์๋ค๋ ๊ฒ์ด๋ค. ๊ฒฐ๊ตญ ์ฐ๋ฆฌ๋ ์๋ก์ด ํด๋์ค์ ๋งค์ง ๋ฉ์๋๋ฅผ ์ฌ์ ์ ํด์ค์ผ๋ก์จ ๋งค์ง ๋ฉ์๋๋ฅผ ๋ชฉ์ ์ ๋ง๊ฒ ์ปค์คํฐ๋ง์ด์งํ๊ฒ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฐ ๊ธฐ์ ์ ์ต์ํด์ง๋ค๋ณด๋ฉด ์ข ๋ low-level ์์ ํ์ด์ฌ์ ๋ค๋ฃฐ ์ ์๋ ์ค๋ ฅ์ด ๋๋ค๊ณ ๋ณผ ์ ์๋ค.
๊ทธ๋ผ ์ด์ ๋งค์ง ๋ฉ์๋ ๊ตฌํํ๋ ์ฝ๋๋ฅผ ์ดํด๋ณด์.
# ๊ณผ์ผ ํด๋์ค๋ฅผ ์ฌ์ฉํด์ ๋ฉ์ง ๋งค์๋ customizing ํ๊ธฐ!
class Fruit:
# ํด๋์ค ๋ณ์ ์ ์
discount_rate = 1.0
def __init__(self, name, price):
self._name = name
self._price = price
# str ๋งค์ง ๋ฉ์๋ ์ ์(ํด๋์ค ํ ๋นํ๊ณ runํ๋ฉด ์ถ๋ ฅ๋๋ ์ ๋ณด)
def __str__(self):
return "{} - {}".format(self._name, self._price)
# add ๋งค์ง ๋ฉ์๋๋ฅผ ๋ด ๋ง๋๋ก ์ ์ํด๋ณด๊ธฐ
def __add__(self, other_inst):
return (self._price + other_inst._price)
# mul ๋งค์ง ๋ฉ์๋๋ฅผ ๋ด ๋ง๋๋ก ์ ์ํด๋ณด๊ธฐ
def __mul__(self, other_inst):
return (self._price * other_inst._price)
# le(less) & ge(greater) ๋์๋น๊ต ๋งค์ง ๋ฉ์๋ ๋ด๋ง๋๋ก ์ ์ํด๋ณด๊ธฐ
def __le__(self, other_inst):
if self._price <= other_inst._price:
return True
return False
def __ge__(self, other_inst):
if self._price >= other_inst._price:
return True
return False
# ํ ์ธ ๋ ๊ฐ๊ฒฉ ์ ๊ณตํ๋ ์ธ์คํด์ค ๋ฉ์๋
def calc_discount(self):
return "Discounted price: {}".format(self._price * Fruit.discount_rate)
# ํ ์ธ๋ฅ ์ปค์คํฐ๋ง์ด์ง ์ํ ํด๋์ค ๋ฉ์๋ ์ ์
@classmethod
def change_rate(cls, rate):
if rate >= 1.0:
print("No longer applied to discount")
cls.discount_rate = rate
# ํ ์ธ์จ ์์นํ
f1 = Fruit('orange', 2000)
f2 = Fruit('melon', 5500)
add = f1 + f2
print(add)
print('-'*50)
mul = f1 * f2
print(mul)
print('-'*50)
print(f1 <= f2)
print('-'*50)
print(Fruit.calc_discount(f1))
print('-'*50)
# ํ ์ธ์จ ๋ณ๊ฒฝ!
Fruit.change_rate(0.5)
print(Fruit.calc_discount(f1))
๊ฒฐ๊ณผํ๋ฉด์ ๋ค์๊ณผ ๊ฐ๋ค. ๋ณด๋ ๊ฒ์ฒ๋ผ ์ผ๋ฐ์ ์ธ +(add), *(mul), ๋์๋น๊ต(le, ge) ๋งค์ง ๋ฉ์๋๋ฅผ ์ฐ๋ฆฌ ์ ๋ง๋๋ก ์ปค์คํฐ๋ง์ด์ง ํ ์ ์๋ค.
๋ค์์ named Tuple์ ์์๋ณด์.
from collections import namedtuple
# ๋ค์๋ ํํ ์ ์ํ๋ ๋ฐฉ๋ฒ(์ด 4๊ฐ์ง)
Point1 = namedtuple('Point1', 'x y')
Point2 = namedtuple('Point2', 'x, y')
Point3 = namedtuple('Point3', ['x', 'y'])
Point4 = namedtuple('Point4', 'x, y, x, class',
rename=True) # ์ค๋ณต๋ key ์ด๋ฆ ๋๋ class๊ฐ์ ์์ฝ์ด ์ด๋ฆ๊ณผ ๋์ผํ ๋ key๊ฐ์ผ๋ก ์ง์ ํด์ฃผ๊ธฐ ์ํ ํ๋ผ๋ฏธํฐ
pt1 = Point1(30, 10)
pt1_2 = Point1(x=30, y=10) # ์ง์ ํ key๊ฐ ์ด์ฉ๋ ๊ฐ๋ฅ
print(pt1)
print(pt1_2)
print('-'*50)
# namedtuple์ ์ด์ฉํด์ ๋ ์ ๊ฐ์ ์ ํด๋ฆฌ๋์ ๊ฑฐ๋ฆฌ ๊ตฌํ๊ธฐ
pt1 = Point1(5, 6)
pt2 = Point1(3, 9)
dist = sqrt((pt1.x - pt2.x)**2 + (pt1.y - pt2.y)**2) # ๋ฌผ๋ก key์ธ x,y๋์ [0],[1] ์ฒ๋ผ ์ธ๋ฑ์ค๋ ์ฌ์ฉ๊ฐ๋ฅํ์ง๋ง ๊ฐ๋
์ฑ์ด key๊ฐ์ ์ด์ฉํ๋ ๊ฒ์ด ๋ ์ข์!
print(dist)
print('-'*50)
#-------------------------------------------------------------------------------------------------
# Dictionary to Namedtuple
temp_dict = {'x': 75, 'y': 55} # key์ด๋ฆ์ namedTuple์ key ์ด๋ฆ๊ณผ ๋์ผํ๋๋ก ์ค์
temp_Point = Point1(**temp_dict)
print(temp_Point)
print('-'*50)
- namedtuple์ key๊ฐ ์๋ tuple ํํ์ด๋ฏ๋ก labeling ํ๊ธฐ ์ข์
- ๊ธฐ์กด Tuple์ ์์์ ์ ๊ทผํ๋ ค๋ฉด ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํด์ผ ํ์ง๋ง namedtuple์ Key๊ฐ์ ์ฌ์ฉํ๋ฉด ๋งค์ฐ ํธ๋ฆฌ
- Key๊ฐ์ด ๋์ผํจ์ด ๊ฐ์ ๋ ๋์ ๋ ๋ฆฌ์์ namedtuple๋ก unpacking์ ํตํด ๋ณํ์ด ๊ฐ๋ฅ
์ด์ namedtuple์ด ๊ฐ๋ ๋ช ๊ฐ์ง ๋ฉ์๋๋ฅผ ์์๋ณด์.
# ๋ค์๋ ํํ ๋ฉ์๋
# 1. _make() : ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑ - list to namedtuple
temp = [52, 39]
temp2 = (52, 39)
pt4 = Point1._make(temp)
pt5 = Point1._make(temp2)
print(pt4)
print(pt5)
# 2. _fields : ํ๋ ๋ค์(namedtuple์ key๊ฐ๋ค) ํ์ธ
print(pt4._fields)
# 3. _asdict() : namedtupe -> OrederedDict๋ก ๋ณํ
print(pt4._asdict()) #๋ํดํธ๋ key ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ๋๋ ๋ฏํจ!
print('-'*50)
- _make : ๋ฆฌ์คํธ ๋๋ ํํ์ namedtuple ํํ๋ก ๋ฐ๊ฟ ์ ์์
- _fields : namedtuple์ ๋ง๋ค ๋ ์ ์ํ๋ key๊ฐ๋ค์ด ๋ฌด์์ธ์ง ํ์ธํ ์ ์์
- _asdict : namedtuple์ ์์๊ฐ์ ๋ ฌ๋ ๋์ ๋๋ฆฌ์ธ Ordereddict ํํ๋ก ๋ณํ ํ ์ ์์
์ด์ namedtuple์ ํ์ฉํ ๊ฐ๋จํ ์ค์ต์ ๊ตฌํํด๋ณด์.
# 4๊ฐ์ ๋ฐ(A,B,C,D)๊ฐ ์๊ณ ๊ฐ 20๋ช
์ ํ์์ด ์์ ๋, ๊ฐ ํ์๋ณ ๋ฐ-๋ฒํธ ๋ค์๋ ํํ ๋ง๋ค๊ธฐ
# namedtuple ์ ์
Classes = namedtuple('Classes', 'room, number')
rooms = 'A B C D'.split()
numbers = [str(n) for n in range(1, 21)]
# ์ด์ค for ๋ฌธ list comprehension ์ด์ฉ
students = [Classes(room=room, number=number) for room in rooms for number in numbers]
print(len(students))
# ์ฝ๋ ๊ฐ๋
์ฑ ์ํ ๋ฆฌํฉํ ๋ง
students = [Classes(room, number)
for room in 'A B C D'.split()
for number in [str(n) for n in range(1, 21)]]
print(len(students))
# ๊ฐ ํ์๋ค์ ๋ฐ-๋ฒํธ ์ถ๋ ฅ
for idx, s in enumerate(students):
print(f"{idx+1}๋ฒ ํ์์ {s.room}๋ฐ, {s.number}๋ฒ ํ์์
๋๋ค.")
'Python > Python' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Python ์ค๊ธ] ์ผ๊ธํจ์(First-class)์ ํด๋ก์ , ๋ฐ์ฝ๋ ์ดํฐ (0) | 2020.12.27 |
---|---|
[Python ์ค๊ธ] Python ์ํ์ค (0) | 2020.12.24 |
[Python ์ค๊ธ] Class์ Method ์ฌํ (0) | 2020.12.20 |
[Python] ํจํค์ง, ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ๋ชจ๋... ๋ ์ง์ง ์์? (0) | 2020.01.07 |
[Python] Class์ Object ๊ฐ๋ ๊ณผ ์ดํด (0) | 2020.01.07 |