namedtuple 정복!

About_work·2023년 2월 24일
0

python 기초

목록 보기
21/56

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))

# 같은 key가 중복되거나, 예약어를 사용하는 경우, rename=True를 사용
Point = namedtuple('Point', 'x y x class', rename=True)

# Ditionary를 unpacking
temp_dict = {'x': 40, 'y': 30}
p1 = Point(**temp_dict)

class가 namedtuple을 사용하기?

  • namedtuple 객체에 method를 추가하고 싶을 떄 사용하자.
from typing import NamedTuple
# 1. 먼저 클래스를 선언하고
class Employee(NamedTuple):
    name: str
    id: int

# 2. 다음과 같이 호출하면 됨
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            # view the field names
>>>
('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)
  • somenamedtuple._asdict()
    • dict로 변환할 떄 씀
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'])
# positional argument를 사용할 수 있고, keyword argument를 사용할 수 있다.
p = Point(11, y=22)
# 필드에 접근할 때는 attribute 이름으로도 가능하다.
p.x + p.y
# 필드에 접근할 때, 숫자 index를 사용해 접근할 수도 있다.
p[0] + p[1]
>>>
33
# unpacking 가능하다.
x, y = p

단점

  • default argument 값 설정이 부자연스럽다.
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글