4-2. Meta Class(2)

uoayop·2021년 3월 27일
0

Leaf와 Python

목록 보기
16/21
post-thumbnail

Mata Class

  • 오늘의 키워드
    • Type 사용법 (name, base, dct)
    • Dynamic Metaclass
    • Meta Class 장점 후킹.(원하는 기능 삽입)

이전 강의 복습

메타 클래스

클래스를 객체라고 생각한 뒤, 클래스를 만들어내는 어떤 것
메타를 기반 으로 붕어빵을 찍어내듯이 클래스를 만든다.

type

메타 자체를 만들어내는 것
이때 type의 메타는 자기 자신이다!

🤣 거의 인셉션 느낌이지만 한마디로 정리하자면,,

  • type이 클래스를 만들어내고, 모든 클래스의 메타는 type이다.
  • 우리가 type까지 손은 댈 수 없지만, 메타 클래스까지는 다룰 수 있다.

동적 생성 메타 클래스 예제

왜 클래스를 동적으로 만드나요? 🤔

동적으로 클래스를 만들 수 있기 때문에, for문과 같은 반복문으로도 클래스를 만들어낼 수 있다.
그래서 DB와 1:1 매핑 하기가 좋아지고, 이는 프레임워크를 만들때 사용할 수 있는 문법이 된다!

type을 이용해서 동적 클래스 생성 시 입력 받는 인자

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의 type은 type이다.
  • 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)

profile
slow and steady wins the race 🐢

0개의 댓글