ПредишенСледващото

Преглед на обектно-ориентираното програмиране

Нека започнем с кратък преглед на това, което е за освобождение на Палестина. В обектно-ориентирани езици за програмиране, можете да определите класове. които свързват помежду си данни и поведение. Класове да наследят всички или някои от характеристиките на родителския клас, но те също могат да определят свои собствени атрибути (данни) и методи (поведение). В крайна сметка класове обикновено служат като образци за създаване на потребителски модели (също понякога се нарича просто обекти). Като правило, в различни инстанции на един клас съдържа различни данни, но всички те са в една и съща форма - например, както обекти Боб служители на служителите и Джейн са заплатите .salary и стая .room_number. но размерът на заплатите и номера на стаята те се различават.

Други статии в тази серия

Някои OOP езици, включително Python, позволяват създаването на предмети от интроспективен (също наречен отразяващ). Интроспективен обекти - обекти, които могат да се опишат: До каква клас принадлежи към този случай? Кой родител елементи има в този клас? Какви методи и атрибути на разположение на този имот? Интроспекция позволява функция или метод, който обработва на обекта, за да вземе решение въз основа на какъв обект се обработват. Дори и без интроспекция, функции често се разклонява на базата на данни, например - например, по пътя към jane.room_number различен начин да bob.room_number. тъй като те са в различни стаи. С интроспекция, можете спокойно да се изчисли размерът на премията за Джейн. без изпълнение изчисляването на Боб. например, защото Джейн има .profit_share атрибут. или защото Боб е например от подклас часове (служителите).

отговор metaprogramming

Основният обектно-ориентиран система, описани накратко по-горе, е много мощен. Въпреки това, в описаното по-горе може да се види още една точка: в класове Python (и други езици) от своя страна са обекти, които могат да се прехвърлят и introspected. Тъй като обектите се, както е отбелязано по-горе, са създадени с помощта на класове, които се използват като шаблони, шаблони са създадени за някои класове? Отговорът е очевиден - това metaclasses.

Metaclasses в Python винаги са били. Въпреки това, механизма на осъществяване на metaclasses тъй като Python 2.2 версия е станал много по-достъпни. По-специално, като се започне с версия 2.2, Python е престанал да бъде езикът на само един специален (най-вече скрити) metaclass, която е създадена въз основа на който и да е обект на класа. Сега програмистът може да създаде подкласове на типа на корен metaclass и дори динамично генериране на класове, които използват различни metaclasses. Разбира се, фактът, че можете да манипулирате metaclasses в Python 2.2, той не обяснява само по себе си, поради които може да се търси.

Освен това, за да създадете свои собствени класове не е нужно обичай metaclasses. Малко по-разбираема концепция е фабрика клас. Нормална функция може да се върне клас, който е създаден динамично в тялото на функция. можете да пишете в традиционния синтаксиса на Python:

Функция class_with_method фабрика () динамично създава и връща клас, който съдържа методи и функции прехвърлени към фабриката. Преди този клас, ще бъде върнат, функцията изпълнява някои операции с него. Новият модул е ​​представен с кратък писмен вид, но без възможност за собствен код в тялото на фабриките на класа, като например:

Във всички тези случаи (Foo. Foo2) поведение на класа не е пряко, предписан в кода, вместо това създава функция разговор в реално време, с динамични аргументи. Трябва да се подчертае, че ние не са динамично създаване на копия на класове. и самите класове.

Metaclasses: решение търси проблем?

Metaclasses - това е много дълбок въпрос, който дори не е нужно да се мисли за 99% от потребителите. Ако не разбирам защо имате нужда от него - така че не е нужно (хора, които действително се нуждаят, се знае точно това, което те се нуждаят от тях, а те не е нужно да се обясни - защо). - Тим Питърс (Тим Питърс), на Python гуру

Методи (класове), както и обичайни функции могат да се върнат обекти. Ето защо, в известен смисъл, очевидно е, че клас фабрики могат да бъдат толкова прости упражнения, те могат да бъдат функции. По-специално, Python 2.2+ изпълнява специален тип клас. който е такъв клас фабрика. Разбира се, читателите ще си спомнят по-малко амбициозен тип функция (). построена през версия на Python старата - за щастие, поведението на стария тип функция () Запис на тип клас (с други думи, вид (OBJ) връща тип / клас на OBJ). Нов клас от тип работи като фабрика клас, по същия начин, като функция new.classobj.

Въпреки това, тъй като сега вида - е (мета) клас, ние сме свободни да го подклас:

Магически методи .__ нов __ () и .__ първоначален __ () имат специален знак, но концептуално те са същите, както всеки друг клас. .__ първоначален __ () метод ви позволява да конфигурирате създадения обект; метод .__ нов __ () ви позволява да настроите местоположението му. Последното, разбира се, не се използва много често, но е възможно за всеки клас, направен в стила на новия Python 2.2 (обикновено наследява, но не заменя).

Синовете тип има една функция, която изисква специално внимание; препънат по него всички, които за първи път работи с metaclasses. Първият аргумент на тези методи обикновено се нарича CLS. а не самостоятелно. защото методите работят с да се създаде клас, а не metaclass. Всъщност, няма нищо специално; всички методи се прикрепят към техните случаи и на инстанция на metaclass е един клас. Изяснява ситуацията малко по-не-специално име:

Всичко това е изненадващо често срещано механика, придружени от някои синтактично удобство, което, от една страна, да я направи по-лесно да се работи с metaclasses, а от друга - са объркващи нови потребители. Този синтаксис включва няколко допълнителни елементи. Въпреки това, процедурата за разрешаване на тези промени е много объркан. Класове да наследят metaclasses от родителите си - имайте предвид, че това не е едно и също нещо, че имат metaclasses като родители (Друга често срещана грешка). За класове стар стил задача глобална променлива _metaclass_ може да доведе до използване на персонализирано metaclass. Въпреки това, в повечето случаи, и това е най-сигурната подход за класа, в който искате да създадете чрез собствената си metaclass определен атрибут клас _metaclass_. Тази променлива трябва да се настрои директно в дефиницията на класа, като metaclass не се използва, когато полето ще се инсталира по-късно (след обект на класа трябва да се създаде). Например:

Реши проблемите с магия

Така че ние обсъдихме основната идея на metaclasses. Въпреки това, използването на metaclasses в истинската работа - доста деликатен въпрос. Проблемът при използването metaclasses е, че в нормалната структура на ООП в действителност класове направи много малко. клас наследство структура е полезна за данните за капсулиране и опаковане и методи, но са склонни да работят само с конкретни случаи.

Както може да се очаква, това приложение отпечатва по-скоро общо описание на обекта на данни (конвенционален инстанция обект). Все пак, ако тази молба при трансфер в реално време, можем да получим много по-различен резултат:

В този пример, сериализация gnosis.xml.pickle. но в най-модерния пакет gnosis.magic съдържа също metaclass serializers MetaYamlDump. MetaPyPickler и MetaPrettyPrint. В допълнение, на потребителя "приложения" dump.py може да изисква използването на който и да е "MetaPickler" от който и Python пакет, в който се изисква такова. Текст metaclass, съответстваща на тази цел ще бъде, както следва:

Един от най-забележителните постижения на този механизъм е, че програмистът писмено заявление не означава непременно знае какво сериализация ще бъде използвана, както и от това дали тя ще бъде добавена към сериализация или някакъв друг крос-технология от командния ред.

Може би най-честата употреба е подобни metaclasses използват MetaPicklers: допълнение, отстраняването и методи за заместване, определени в класа установена. В нашия пример, "оригинал" метода на Data.dump () се заменя с друг, създаден извън приложението, по време на класа на данни (и следователно във всяка следваща инстанция).

Други начини за решаване на проблеми, свързани с магия

Ако се опитате да създадете инстанция на класа на дисертация, без необходимите компоненти вложени елементи, описателен грешка ще бъдат върнати; същото се отнася и за всеки под-елемент. Правилните отделните елементи ще бъдат създадени от по-прости аргументи, когато има само един начин недвусмислено "повдигане" на аргументите на правилния тип.

Дори въпреки факта, че класовете на изпитване често (неофициално) са базирани на вече съществуващи на DTD, копия на тези класове се извличат като неоформен фрагменти от документ за XML, като например:

Пакет gnosis.xml.validity не знае нищо за DTD и вътрешния подгрупа. Като цяло, тези понятия и възможности са metaclass DTDGenerator. без каквито и да било промени в gnosis.xml.validity и simple_diss.py. DTDGenerator не замества със собствен метод .__ ул __ () в класа са ги създали - можете да печатате безформена фрагмент на XML - но това metaclass позволява лесно да променяте тези магически методи.

Инструменти за metaclasses

В gnosis.magic пакет съдържа няколко помощни програми за работа с metaclasses, както и някои примери за metaclasses можете да използвате в аспект-ориентираното програмиране. Най-важните от тези инструменти е import_with_metaclass (). Тази функция се използва в горния пример, като ви позволява да импортирате модул от трета страна, но се създаде всички класове модул с помощта на потребителски metaclass, а не тип. Можете да определите в създадения от вас (или дори вземат от някъде другаде) metaclass всяка нова възможност, която искате да влиза в модул на трета страна. gnosis.magic съдържа няколко metaclasses щепсела сериализация; други пакети за опазване на радиоактивен изотоп на обекти, за регистриране на грешка и т.н.

import_with_metclass () функция илюстрира няколко предимства на програмиране с metaclasses:

Една от функциите на тази функция е, че един обикновен клас Meta е създаден с помощта на посочения metaclass. Въпреки това, след добавяне на Мета като майка му потомци също са създадени от специална metaclass. По същество, като мета класове могат да носят metaclass и създател, както и набор от наследствени методи - от двете страни на неговото наследство независими една от друга.

Изтегляне ресурси

Свързани теми

Подкрепете проекта - споделете линка, благодаря!