classDataObjectType(type):def__init__(mbs,name,bases,dct):super(DataObjectType,mbs).__init__(name,bases,dct)# 將建好的class的__init__ function 設為 clsinitmbs.__init__=clsinit# 將建好的class的__repr__ function 設為 clsreprmbs.__repr__=clsreprdefclsinit(self,**kwargs):# 更新self, 也就是建構好的instance的attributesself.__dict__.update(kwargs)defclsrepr(self):# 顯示 DataObject(a=1,b=2)這樣的字串return"{}({})".format(self.__class__.__name__,','.join(["{}={}".format(k,v)fork,vinself.__dict__.items()]))# 將Value class 的 type 改成 DataObjectType, 原本應該是object的type (也就是type)# 你可以在python interpreter裡打 type(object) 看一下結果 :pclassValue(object):__metaclass__=DataObjectType# here we go!v=Value(x=1,y=2,z=3)printv.x# 1
#首先, 沒有設定readonly的狀態下>>>obj=Value(x=3)#成功設定x為4>>>obj.x=4#再來把Value設為readonly>>>Value.readonly=True>>>obj=Value(x=3)# 沒辦法把x設成4, 成功!>>>obj.x=4Traceback(mostrecentcalllast):File"",line1,inFile"metaclass.py",line41,inclssetattrraiseAttributeError("can't set attribute")AttributeError:can't set attribute
結論
在Refactory一書中, 建議使用data object來減少需要傳遞的參數, 而Python又可以使用property使得getter function 使用方式與讀取attribute 一模一樣, 使得data object在python裡面更powerful.