Форум программистов, компьютерный форум, киберфорум
Фаер
Войти
Регистрация
Восстановить пароль

Python. ООП. Трансформинг и КП.

Запись от Фаер размещена 31.08.2013 в 13:08
Показов 4268 Комментарии 0

Мы уже немало говорили об объектно-ориентированном программировании. Создание своих собственных классов, наследование, прототипирование - это очень удобно. Но это ещё не всё. Python, будучи объектно-ориентированным языком, делает парадигму ООП более гибкой, чем это может показаться на первый взгляд. Сейчас Мы разберём компонентное программирование - ещё один стиль ООП, который вполне можно реализовать на Python.

Компонентное программирование(КП) предусматривает использование компонентов - определённых структурированных частей кода. Эти компоненты подключаются к уже готовым объектам, расширяя их возможности. Разбирая декораторы, Мы говорили о том, что в Python'е функции и даже классы являются объектами. Это свойство Нам сейчас и пригодится.

Для начала напишем простенький класс:

Python
1
2
3
4
5
class chameleon:
    def __init__(self,color,age,weight):
        self.color=color
        self.age=age
        self.weight=weight
Давайте с помощью функции dir() выведем список атрибутов этого класса и оставим его где-нибудь на видном месте.

Теперь опишем компонент - функцию. При этом по форме своей она будет похожа на метод:

Python
1
2
def chcolor(self,col):
    self.color=col
Функция - это объект, который Мы можем присвоить какой-нибудь переменной. Например, Мы можем присвоить её классу в качестве атрибута:

Python
1
chameleon.chcolor=chcolor
Давайте ещё раз воспользуемся dir(chameleon) и посмотрим на новый список атрибутов. Появился новый атрибут - chcolor. Это Наш компонент. Дабы убедиться в том, что компонент правильно встроился в класс, инстанцируем объект и обратимся к методу chcolor():

Python
1
2
3
cham=chameleon('red',5,50)
cham.chcolor('blue')
print(cham.color)
Как видите, объект cham использует функцию chcolor() как свой собственный метод. При этом сама функция может находиться где угодно за пределами описания класса. Но это ещё не всё. Попробуйте сначала инстанцировать объект, а потом присвоить классу(не объекту!) ещё один метод. Удивительно, но готовый объект так же приобретёт новый метод. Некоторое неудобство заключается в том, что все объекты, принадлежащие классу chameleon(), приобретут этот новый метод. О том, как этого избежать, Мы поговорим чуть ниже. А сейчас давайте, наоборот, удалим метод. Для этого Нам понадобится оператор del:

Python
1
del chameleon.chcolor
Заметьте, все экземпляры класса chameleon(), потеряют удалённый метод.

С трансформацией классов всё оказалось просто. Но иногда нужно изменить не весь класс, а только один его экземпляр. Обычное присваивание тут не поможет. Казалось бы, почему нет!? Сейчас разберёмся. Используем тот же класс chameleon() и функцию chcolor():

Python
1
2
3
ch=chameleon('red',5,50)
ch.chcolor=chcolor
ch.chcolor('yellow')
В ответ Мы получим что-то, вроде: "TypeError: chcolor() missing 1 required positional argument: 'col'". Если Вы не забыли, методы получают сущность объекта, которому они принадлежат, первым аргументом, который принято называть self. Передача происходит неявно. Однако, в Нашем случае, функция остаётся функцией, а значит, никакого self она получать не будет. Таким образом, функция принимает первый аргумент self явно, присваивая ему значение 'yellow'. Можно, конечно, избежать этого, каждый раз явно передавая объект первым аргументом, но это не удобно.

Убедиться в том, что после присваивания функция осталась функцией можно с помощью инструкции:

Python
1
ch.chcolor.__class__
Ответом будет <class 'function'>. Если Вы используете эту конструкцию для получения класса метода, то обнаружите, что метод(<class 'method'>) и функция - это не одно и то же. У методов, есть атрибут __self__, который при вызове неявно указывает объект self. Но, даже добавив функции аналогичный атрибут __self__, указывающий на объект, Вы не решите проблему.

Поможет Нам в данном случае модуль types. В нём содержится класс MethodType(), который исправит все недоразумения, тревожащие Нас на протяжении последних двух абзацев:

Python
1
2
3
4
5
6
7
8
9
10
11
12
from types import MethodType
class clameleon:
    def __init__(self,color,age,weight):
        self.color=color
        self.age=age
        self.weight=weight
 
def chcolor(self,col):
    self.color=col
 
obj=chameleon('red',5,50)
obj.chcolor=MethodType(chcolor,obj)
Вот это уже на что-то похоже. Теперь объект obj приобрёл полноценный метод chcolor(). Заметьте, что MethodType() принимает два аргумента: функцию и объект, к которому будет привязана функция. При этом, изменения будут проведены только в объекте obj. Инстанцировав второй объект, Вы обнаружите, что метода chcolor() он не имеет. То есть, сам класс остался нетронутым.

С удалением методов проблем нет. Нам понадобиться тот же оператор del, который без лишних заморочек удалит любой атрибут уже готового объекта.

На этом Мы закончим. Не проходите мимо компонентного программирования. Ведь модификация класса в любой точке программного кода очень удобна. Вам не нужно искать описание класса, возможно, находящееся в далеко сидящем модуле. Ну а трансформинг готовых объект - это просто вишенка на торте.
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru