@ ThiefMaster 님의 방법대로 투표 할 것입니다.
from functools import wraps
class PreprocessMetaclass(type):
def __new__(cls, name, bases, dct):
try:
if Data in bases and "preprocess_data" in dct:
f = dct["preprocess_data"]
@wraps(f)
def preprocess_data(self, *args, **kwargs):
self.data = self.data.copy()
return f(self, *args, **kwargs)
attrs = dct.copy()
attrs["preprocess_data"] = preprocess_data
except NameError as e:
# This is if Data itself is being created, just leave it as it is.
# Raises an NameError, because Data does not exist yet in "if Data in bases"
attrs = dct
return super(PreprocessMetaclass, cls).__new__(cls, name, bases, attrs)
class Data(object):
# This here works if the subclasses don't specify
# their own metaclass that isn't a subclass of the above.
__metaclass__ = PreprocessMetaclass
def __init__(self, data):
self.data = data
self.valid = False
#Analyze and validate data
self.preprocess_data()
self.validate_data()
def preprocess_data(self):
self.data["newkey"] = 3
def validate_data(self):
print "This is the result: self.data =", self.data
class MyData(Data):
def __init__(self, data):
super(MyData,self).__init__(data)
def preprocess_data(self):
"""The docs of the subclass"""
self.data["newkey"] = 4
if __name__ == "__main__":
dct1, dct2 = {"data": 1}, {"mydata": 2}
print "Create Data"
d = Data(dct1)
print "Create MyData"
md = MyData(dct2)
print "The original dict of Data (changed):", dct1
print "The original dict of MyData (unchanged):", dct2
# If you do that, you will see that the docstring is still there,
# but the arguments are no longer the same.
# If that is needed (you don't have arguments, but the subclass might have)
# then just enter the same arguments as the subclass's function
# help(MyData)
PS 그것은 내가 메타 클래스를 사용하는 데 필요한 처음이지만, 여기 완벽한 시나리오는 다음과 같습니다 당신이 당신의 인생을 복잡하게하려면 decorators와 metaclasses를 사용할 수 있습니다. 클래스가 생성되기 전에 함수 정의를 재정의해야합니다 (__init__
전). 자, 당신은 그것을 필요로하지 않을 수도 있지만, 더 일반적으로, 당신은 그것을 사용하도록 강요받을 수도 있습니다.
이보다 더 간단한 예 :
if not (self.preprocess_data is Data.preprocess_data):
self.data = self.data.copy()
self.preprocess_data()
간결하고 작업이 완료됩니다. @ ThiefMaster. 감사합니다. – Bastiano9