Programming Language/Python
Effective Python. 메타클래스로 클래스 속성에 주석을 달자.
알파해커 테크노트
2021. 3. 3. 00:32
반응형
메타클래스와 디스크립터를 활용하면, 중복 코드를 좀 더 줄이고 깔끔한 코드를 만들 수 있다.
아래와 같은 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()
반응형