2012-04-14

Python Metaclass


Энгийн байна гэдэг бол 
Маш олон асуудалыг шийдэх шидэт түлхүүр

Би ойрд ажил ихтэй код бичээд амралт багатай. Өлөө ирээд нухаж гарна орой болтол нухаад л байна. Гэдэг шиг ажил ихтэй завгүй талдаа л байна. Хавар цаг болоод олон хүмүүс хямралдаад за за хадуурлаа... гол хэсэгрүүгээ ороё.

Нэг сонирхолтой сэдэв нэлээд дээхэн үед Learning python гээд хальт нэг оньсого шиг юм бичсэн тэрний 1-р бичигдсэн Metaclass ийн хэрэглээний талаар товчхон ойлголт өгөх гэж оролдоё. Энэ аргийг маш өргөн хэрэглэж байгаа учраас зарим Framework ийн кодруу харж байгаад жишээ болгоод тайлбарлая. 

Django ийн талаар олон юм нурших нь илүү байх. Харин Django ийн forms.Form классыг бүгд мэдэх байх. Энэ нөхөр хэрхэн ажиллаж байгааг арай өөр өнцөгөөс харая.

Бид form class ийг бичихдээ ихэвчлэн дараах хэлбэрээр бичдэг. 

Loading ....


Энэ хэсэг бол ямар нэг илүү юм бичигдэхгүй тун жижхэн код байгаа. Хэрхэн ашиглах энэ сэдэвт хамаагүй учир орхилоо. 

Харин яаж ажиллаад байгааг нь тайлбарлая. Бидны класс forms.Form классаас удамшисан байгаа. Энэ классын зарлалт нь forms.py#L383 мөр дээр байгааг харж болно. Энэ класс нь BaseForm классаас удамшиж байгаа. Мөн нэг __metaclass__ гэсэн талбарт DeclarativeFieldsMetaclass утгыг өгсөн байгааг харж болно. 
Loading ....

Завсарлага 5 мин :)




DeclarativeFieldsMetaclass нь type классаас удамшиж байгаа энэ нь Python ийн үндсэн object классын үүсгэгч класс. энэ класс нь __new__ функцийг дахин тодорхойлож бүх талбарууд (attrs) дээр үйлдэл хийж байгааг харж болно. Энэ функ нь python ийн process үүсэх үед нэг удаа ажилладаж class төрлийн instance ийг үүсгэн бэлтгэж байгаа учираас классийн __init__ функцээс ялгаатай.

Loading ....


Дээрх кодын __new__ функц дотор get_declared_fields функцийн үр дүнг base_fields талбар үүсгэн хадгалаж байгааг харж болно. Энэ base_fields талбарийн хэрэглэж байгаа байдалийг BaseForm classын __init__ функц дотор  self.fields = copy.deepcopy(self.base_fields) гэсэн мөрийг анхаарах хэрэгтэй энэ нь яагаад copy хийж байгаа шалтгаанаа тайлбарлаж бичсэнийн анхааралтай уншаарай. Шалтгаан нь base_fields ийг шинэ Form instance -уудыг үүсгэх үед хэрэглэж байгаа учраас.

За товчхондоо metaclass ийг django дээр иймэрхүү байдалаар хэрэглэж байгаа. Энэ нь тухайн framework ийг хэрэглэж байгаа хүний бичих кодыг багасгах цэгцтэй болгох гэх мэт маш олон давуу талуудыг үүсгэж байгааг харж болно. Мөн Django ийн Model дээр metaclass хэрэглэж байгааг үзэж болно.

Цаашлаад metaclass-ийг удамшилуулах class уудын удамшилд хэрхэн нөлөөлөж байгааг хараахан ойлгож амжаагүй байгаа....