namedtuple
언제 써야해?
- 완전한 class 가 제공하는 유연성이 필요하지 않고, 작은 불변 데이터 container가 필요할 때
- tuple 의 특성인 불변성과, dictionary의 장점인 label 있음을 둘 다 쓰고 취하고 싶을 때
- tuple의 원소가 4개 이상이 되어서, 각 원소가 어떤 것을 내포하고 있는지 기억하기 힘들어질 때
정의 방식
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
Point = namedtuple('Point', 'x y')
Point = namedtuple('Point', 'x, y')
fields = ('value', 'left', 'right')
Node = namedtuple('Node', fileds, defaults=(None, ) * len(fields))
Point = namedtuple('Point', 'x y x class', rename=True)
temp_dict = {'x': 40, 'y': 30}
p1 = Point(**temp_dict)
class가 namedtuple을 사용하기?
- namedtuple 객체에 method를 추가하고 싶을 떄 사용하자.
from typing import NamedTuple
class Employee(NamedTuple):
name: str
id: int
employee1 = Employee('Guido', 2)
print(employee1)
print(employee1.name, employee1.id)
print(employee1[0], employee1[1])
Car = namedtuple('Car', ['color', 'mileage'])
class MyCarWithMethods(Car):
def hexcolor(self):
if self.color == 'red':
return '#ff0000'
else:
return '#000000'
c = MyCarWithMethods('red', 1234)
c.hexcolor()
'#ff0000'
메서드 종류
- classmethod
somenamedtuple._make(iterable)
- 이미 존재하던 sequence나 iterable로 부터, 새 instance를 만드는 class method
t = [11, 22]
Point._make(t)
>>>
Point(x=11, y=22)
somenamedtuple._fields
- field 이름들(str)을 리스팅한 tuple을 반환함.
- field들을 확인하거나, 존재하는 naed tuples로부터 새로운 named tuple을 만드는데 유용하다.
p._fields
>>>
('x', 'y')
Color = namedtuple('Color', 'red green blue')
Pixel = namedtuple('Pixel', Point._fields + Color._fields)
Pixel(11, 22, 128, 255, 0)
>>>
Pixel(x=11, y=22, red=128, green=255, blue=0)
somenamedtuple._field_defaults
- field names와 default values를 dictionary mapping할 떄 쓰임
Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
Account._field_defaults
>>>
{'balance': 0}
Account('premium')
>>>
Account(type='premium', balance=0)
p = Point(x=11, y=22)
p._asdict()
{'x': 11, 'y': 22}
somenamedtuple._replace(**kwargs)
- 특정 fields를 새로운 values로 바꾼, 새로운 instance of the named tuple을 return
p = Point(x=11, y=22)
p._replace(x=33)
Point(x=33, y=22)
for partnum, record in inventory.items():
inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
장점
- positional argument를 사용할 수 있고, keyword argument를 사용할 수 있다.
- 필드에 접근할 때는 attribute 이름으로도 가능하고, 숫자 index를 사용해 접근할 수도 있다.
- unpacking 가능 /
__repr__
사용 가능
- attribute 값에 대한 iteration도 가능하다.
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22)
p.x + p.y
p[0] + p[1]
>>>
33
x, y = p
단점
- default argument 값 설정이 부자연스럽다.