이전 강의 복습
메타 클래스
클래스를 객체라고 생각한 뒤, 클래스를 만들어내는 어떤 것
메타를 기반 으로 붕어빵을 찍어내듯이 클래스를 만든다.type
메타 자체를 만들어내는 것
이때 type의 메타는 자기 자신이다!
🤣 거의 인셉션 느낌이지만 한마디로 정리하자면,,
- type이 클래스를 만들어내고, 모든 클래스의 메타는 type이다.
- 우리가 type까지 손은 댈 수 없지만, 메타 클래스까지는 다룰 수 있다.
동적으로 클래스를 만들 수 있기 때문에, for문과 같은 반복문으로도 클래스를 만들어낼 수 있다.
그래서 DB와 1:1 매핑 하기가 좋아지고, 이는 프레임워크를 만들때 사용할 수 있는 문법이 된다!
type(name, bases, dct)
- name(클래스의 이름)
- bases(상속되는 클래스가 있는지 )
- 다중 상속이 가능하니까 bases는 튜플 형태로 넣는다.
- 모든 클래스는 object를 상속 받으므로, 상속을 받지 않을 땐 비워두거나 object를 써도 된다.
- dct(속성이나 메소드)
- dictionary 형태로 묶어서 넣는다.
s1 = type('Sample1',(),{})
print('ex 1>',s1)
# ex 1> <class '__main__.Sample1'>
print('ex 1>',type(s1))
# ex 1> <class 'type'>
동적 생성한 Sample1 클래스
s1
의 메타 클래스는 type
이다.
s1
자체가 sample1 클래스
가 되는거고, 타입 메타 클래스를 기반으로 만들어졌음을 의미한다.
다음은 정적으로 만든 클래스다.
class Sample:
pass
s = Sample()
print('ex 1>',s)
# ex 1> <__main__.Sample object at 0x7fe370260280>
print('ex 1>',type(s))
# ex 1> <class '__main__.Sample'>
print('ex 1>',type(type(s)))
#ex 1> <class 'type'>
정적으로 만든 클래스 Sample
의 인스턴스 s
의 type은 Sample
이다.
다른 클래스를 상속할 때, type의 두번째 인자
bases를 이용한다.
# 상속할 클래스
class Parent1:
pass
s2 = type(
'Sample2',
(Parent1,),
dict(attr1=100, attr2='hi')
)
s2는 Parent 클래스를 상속하고, 이름이 'Sample2' 인 클래스이다. 속성으로는 attr1=100, attr2='hi'
를 갖고있다.
클래스 Sample2
는 아래와 같은 코드로 정적 생성이 가능하다.
class Sample2(Parent1):
attr1=100
attr2='hi'
동적으로 생성한 s2를 출력해보자
s2.__base__
로 알 수 있다.s2.__dict__
로 속성을 확인할 수 있다.print('ex 2> ',s2)
#ex 2> <class '__main__.Sample2'>
print('ex 2> ',type(s2))
#ex 2> <class 'type'>
print('ex 2> ',s2.__base__)
#ex 2> <class '__main__.Parent1'>
print('ex 2> ',s2.__dict__)
#ex 2> {'attr1': 100, 'attr2': 'hi', '__module__': '__main__', '__doc__': None}
print('ex 2> ',s2.attr1, s2.attr2)
#ex 2> 100 hi
type 함수로 메타 클래스를 동적 생성할 때 내부에 메소드를 정의해보자
한번 쓰는 함수이니까 lambda 를 이용해서 작성해보았다.
s4 = type(
'Sample4',
(object, ),
{
'attr1':10,
'attr2':20,
'add':lambda x,y : x+y,
'mul':lambda x,y : x*y,
}
)
관련 내용을 출력해보자
print('ex 3>', s4)
# ex 3> <class '__main__.Sample4'>
print('ex 3>', type(s4))
#ex 3> <class 'type'>
print('ex 3>', s4.attr1,s4.attr2)
#ex 3> 10 20
print('ex 3>', s4.add(10,20), s4.mul(10,20))
#ex 3> 30 200
print('ex 3>', s4.__base__)
#ex 3> <class 'object'>
print('ex 3>', s4.__dict__)
#ex 3> {'attr1': 10, 'attr2': 20,
# 'add': <function <lambda> at 0x7fe0665ba160>,
# 'mul': <function <lambda> at 0x7fe06829b4c0>,
# '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Sample4' objects>,
# '__weakref__': <attribute '__weakref__' of 'Sample4' objects>, '__doc__': None}
정리
- type 함수를 이용해서 동적으로 메타 클래스를 만들 수 있다.
- type함수는 3가지 인자를 필요로 한다.
(name, bases, dct)
name
: 클래스 이름
bases
: 상속받는 클래스
- 없으면 비워두거나 object를 적는다.
- 여러 개를 상속받을 수 있으므로 tuple 형태
dct
: 내부 선언되는 속성이나 메소드
- dictionary 형태
[출처]
인프런 - 모두를 위한 파이썬 : 필수 문법 배우기 Feat. 오픈소스 패키지 배포 (Inflearn Original)