파이썬과 객체지향 프로그래밍 - . 파이썬만의 특별한 클래스 작성 기법 (namedtuple) (심화)

14. 파이썬만의 특별한 클래스 작성 기법 (namedtuple) (심화)

14.1. collections.namedtuple

클래스없이 객체를 생성할 수 있는 방법 - 클래스에 attribute만 있는 경우만 해당함!

  • tuple 클래스를 활용
  • attribute 만 있는 클래스의 경우만 해당됨
In [1]:
import collections

클래스에 attribute만 있는 경우는 왜 있나?

C언어는 변수를 묶어서 하나의 변수로 쓸 수 있는데요. 파이썬에서는 이와 같은 방식으로 사용가능

struct student {
  int id;
  char *name;
};

int main() {
    struct student s;
    s.id=1;
    s.name = "김철수";
}

사용법:

  • 클래스명 = collections.namedtuple('실제 클래스명', [각 튜플 데이터 이름 리스트])
    • Employee = collections.namedtuple('Person', ['name', 'id'])
  • 클래스명 = collections.namedtuple('실제 클래스명', '각 튜플 데이터 이름을 한칸씩 띄우면서 나열')
    • Employee = collections.namedtuple('Person', 'name id')
In [22]:
Employee = collections.namedtuple('Person', ['name', 'id'])    # 리스트로 써도 되고!
employee1 = Employee('Dave', '4011')
print (employee1)
print (type(employee1))
Person(name='Dave', id='4011')
<class '__main__.Person'>
In [21]:
Employee = collections.namedtuple('Person', 'name, id')        # 스트링처럼 써도 됨
employee1 = Employee('Dave', '4011')
print (employee1)
print (type(employee1))
Person(name='Dave', id='4011')
<class '__main__.Person'>

Person과 Employee 관계

  • Employee = Person 의미, Employee가 Person 이라는 실제 클래스를 참조 (가리킴)
  • 헷깔리는 부분으로 보통은 다음과 같이 동일한 클래스 이름을 사용
    • Employee = collections.namedtuple('Employee', ['name', 'id'])
In [20]:
Employee = collections.namedtuple('Employee', ['name', 'id'])
employee1 = Employee('Dave', '4011')
print (employee1)
print (type(employee1))
Employee(name='Dave', id='4011')
<class '__main__.Employee'>


다음과 같이 명시적으로 속성명을 적을 수도 있음

In [3]:
Employee = collections.namedtuple('Employee', ['name', 'id'])
employee2 = Employee(id='4012', name='David')
print (employee2)
Employee(name='David', id='4012')

속성을 다루는 방법

In [5]:
Employee = collections.namedtuple('Employee', ['name', 'id'])

employee1 = Employee('Dave', '4011')
employee2 = Employee('David', '4012')

# 일반적인 튜플 처럼 속성 접근 (권장하지는 않음, 추후 일반 클래스로 바꾼다면 관련 코드를 모두 변경해야함)
print (employee1, employee1[0], employee1[1])
print (employee1.name)
Employee(name='Dave', id='4011') Dave 4011
Dave
In [6]:
# 일반적인 튜플처럼 속성값을 각 변수에 가져올 수 있음
name, id = employee2

print(name, id)
David 4012
초간단 연습1
1. 직장인 이름, 나이, 부서를 속성으로 갖는 기존과 같은 방식으로 class를 만들고,
- 세 개의 객체를 임의 속성값과 함께 넣어보고, 각각을 출력해보기
2. 이번에는 직장인 이름, 나이, 부서를 속성으로 갖는 class를 namedtuple 로 정의하고,
- 세 개의 객체를 임의 속성값과 함께 넣어보고, 각각을 출력해보기
In [8]:
class EmployeeClass:
    def __init__(self, name, id, org):
        self.name = name
        self.id = id
        self.org = org

employee2 = EmployeeClass('Dave', '4011', 'sales')
print (employee2.name, employee2.id, employee2.org)


Employee = collections.namedtuple('Employee', ['name', 'id', 'org'])
employee1 = Employee('Dave', '4011', 'sales')
print (employee1.name, employee1.id, employee1.org)
Dave 4011 sales
Dave 4011 sales

14.2. typing.NamedTuple

  • 파이썬 3.6에서 추가된 클래스 (collections.namedtuple 의 개선 방식?)
  • 파고들면 끝이 없긴 합니다, 가벼운 마음으로 참고


사용법:

  • 가독성이 조금 나아졌다고도 하는데, 어떠신지?
In [13]:
from typing import NamedTuple
# 1. 먼저 클래스를 선언하고
class Employee(NamedTuple):
    name: str
    id: int
In [12]:
# 2. 다음과 같이 호출하면 됨
employee1 = Employee('Guido', 2)
print(employee1)
print(employee1.name, employee1.id)
print(employee1[0], employee1[1])
Employee(name='Guido', id=2)
Guido 2
Guido 2

디폴트값도 선언할 수 있음 (파이썬 3.6.1 부터)

In [25]:
from typing import NamedTuple

class Employee(NamedTuple):
    name: str
    id: int = 3
employee1 = Employee('Guido')
print(employee1)
print(employee1.name, employee1.id)
print(employee1[0], employee1[1])
Employee(name='Guido', id=3)
Guido 3
Guido 3
In [15]:
from typing import NamedTuple
class Employee(NamedTuple):
    name: str = 'Guido'
    id: int = 3
employee1 = Employee()
employee2 = Employee('Dave', 4)
print(employee1)
print(employee1.name, employee1.id)
print(employee2.name, employee2.id)
Employee(name='Guido', id=3)
Guido 3
Dave 4
초간단 연습2
직장인 이름, 나이, 부서를 속성으로 갖는 class를 typing.Namedtuple 로 정의하고,
- 세 개의 객체를 임의 속성값과 함께 넣어보고, 각각을 출력해보기
In [29]:
from typing import NamedTuple
# 1. 먼저 클래스를 선언하고
class Employee(NamedTuple):
    name: str
    id: int
    org: str


In [30]:
employee2 = Employee('Dave', 4, 'sales')
print (employee2.name, employee2.id, employee2.org)
Dave 4 sales