반응형
메타클래스와 디스크립터를 활용하면, 중복 코드를 좀 더 줄이고 깔끔한 코드를 만들 수 있다.
아래와 같은 Field 디스크립터가 있다고 가정해보자.
class Field:
def __init__(self, name):
self.name = name
self.internal_name = '_' + self.name
def __get__(self, instance, instance_type):
if instance is None:
return self
return getattr(instance, self.internal_name, '')
def __set__(self, instance, value):
setattr(instance, self.instance_name, value)
그리고, Field 디스크립터를 이용해, Customer 클래스의 각 속성 값을 만든다면 다음과 같이 만들어 질 것이다.
class Customer:
first_name = Field('first_name')
last_name = Field('last_name')
prefix = Field('prefix')
suffix = Field('suffix')
그러나, fisrt_name 이라는 속성명과
해당 속성을 만들어주기 위한 Field 디스크립터의 파라미터로 넘기는 'first_name'이라는 문자열이 중복처럼 느껴진다.
(last_name, prefix, suffix 모두 마찬가지)
이 중복을 제거할때 메타클래스를 활용할 수 있다.
아래와 같이, 인스턴스의 속성이 디스크립터(Field)인 경우, 해당 디스크립터 인스턴스의 속성에 접근하여 값을 할당하면 된다.
class Meta(type):
def __new__(meta, name, bases, class_dict):
for key, value in class_dict.items():
if isinstance(value, Field):
value.name = key
value.internal_name = '_' + key
cls = type.__new__(meta, name, bases, class_dict)
return cls
이렇게 만든 메타클래스를 이용하여 기반클래스를 만들고(여기서는 DatabaseRow라는 이름의 기반 클래스를 만들어보자).
그 후, 만들어진 기반클래스를 이용하여, 원래 만들고자 했던 Customer 클래스를 만들면 된다.
class DatabaseRow(metaclass=Meta):
pass
class BetterCustomer(DatabaseRow):
first_name = Field()
last_name = Field()
prefix = Field()
suffix = Field()
반응형
'Programming Language > Python' 카테고리의 다른 글
[파이썬/Python] 숫자/문자열 앞에 "0" 채우기 (1) | 2021.06.08 |
---|---|
[파이썬/Python] 문자열을 변수로 만들기, globals() locals() (0) | 2021.06.02 |
Effective Python. 메타클래스로 서브클래스를 검증하자. (0) | 2021.03.03 |
Effective Python. 지연 속성에는 __getattr__, __getattribute__, __setattr__을 사용하자. (0) | 2021.03.02 |
Effective Python. 재사용 가능한 @property 메서드에는 디스크립터를 사용하자. (0) | 2021.03.02 |