====== Модули и пакеты. ООП ====== ===== Модули и пакеты ===== **Любой файл с кодом**, является модулем. Импортированный модуль может содержать программу на С.\\ Запускаемый модуль всегда называется **__main__**, доступно через атрибут "__name__"\\ ==== import ==== import <название модуля> [as <Псевдоним>]\\ Название без расширения и т.д., создается одноименный идентификатор, наравне с переменными, через который в дальнейшем и доступно содержимое модуля.\\ Проверить существование атрибута- **hasattr()**\\ Перед выполнением каждый модуль компилируется в байт-код, откомпилированные файлы (*.pyc) хранятся в **__pycache__**, их тоже можно импортировать и использовать\\ Импорт производится при первом вызове, затем кэшируется в **sys.modules**\\ **__import__('str')** - динамический импорт, название из строки (переменной)\\ ==== from ==== Для импортирования только определенных идентификаторов\\ **from <модуль> import <идентификатор> or (id1, id2 ..)**\\ ==== Пути поиска модулей ==== Хранятся в переменной **sys.path**. Можно изменять программно- append()\\ * папка со скриптом * переменная окружения **PYTHONPATH** * пути к стандартным модулям * содержимое в файлах ** *.pth ** ==== Повторная загрузка модулей ==== Импортируется один раз, для повторной загрузки ф-я **imp.reload()**\\ ==== Пакеты ==== Папка с модулями, в которой расположен файл инициализации **__init__.py**- может быть пустым либо содержать код для первой инициализации при импортировании любого модуля из этого пакета\\ ===== Объектно-ориентированное программирование ===== В отличии от функционального подхода, позволяет описать предметы мира в виде сущностей и организовать связи между ними.\\ ==== Определение класса, создание экземпляра ==== class <Название класса> [(<родит. классы>,...<..>)]: """ Строка документирования """ <Св-ва / Методы> В момент описания, **создается полноценный объект**. Выполнение **происходит в месте определения** а не создания экземпляров\\ Всем методам, обязательно, первым параметром **передается ссылка на экземпляр** класса (**self**), либо вызывать ф-ю из объекта\\ Все атрибуты и методы являются **public**, можно закрывать костылями\\ * **getattr(, , =)** - значение атрибута, либо исключение, название можно формировать динамически * **setattr()** - установить значение, если атрибут не существует, то будет создан * **delattr() / hasattr()** - удалить / проверка существования Атрибуты классу (не объекту а именно классу) **можно создавать в коде, динамически** (собсна функции выше)\\ class MyClass: pass MyClass.x= 50 c1, c2= MyClass(), MyClass() c1.y= 10 c2.y= 20 print(c1.x, c1.y) # 50 10 print(c2.x, c2.y) # 50 20 ==== __init__()/__del__() ==== Конструктор/Деструктор (в скриптовой специфике python, последний особо смысла не имеет)\\ ==== Наследование ==== Вроде ничего необычного, public-наследование..\\ Конструктор базового класса можно переопределять в производном\\ ==== Множественное наследование ==== В случае пересечения названий, порядок поиска соответствует порядку перечисления классов в описании\\ === Примеси и их использование === Что то вроде понятия абстрактного класса\\ class myMixin: # Класс "примеси" attr= 0 # Атрибут такого класса def mix_met(self): pass class Class1 (MyMixin): def meth1(): pass class Class2 (Class1, MyMixin): ... ==== Специальные методы ==== В основном благодаря им можно переопределить (перегрузить) стандартные функции, типа преобразования, проверка длинны и т.д., такие как: __call__() (типа д-е по умолчанию, при вызове объекта без методов), __getattr__ (set/del), __bool__(), __int__(), __float__() и т.д.\\ ==== Перегрузка операторов ==== Аналогично, целый ряд спец функций для этого: __add__(), __sub__(), __mul__() и т.д. оч много..\\ ==== Статические методы и методы класса ==== Статические методы создаются с помощью декоратора "@staticmethod". При вызове такого, self указывать собсна не нужно\\ Методы класса, декоратор "@classmethod", первым параметром передается ссылка на класс\\ class MyClass: @staticmethod # Декоратор def func1(): # Статический метод pass def func2(): # Обычный метод pass ==== Абстрактные методы ==== Абстрактные классы содержат только определения методов, без реализации\\ Для верности можно вызывать исключение в функции\\ Так же есть декоратор "@abstractmethod" class Class1: def func1(self, x): # Абстрактный метод raise NotImplementedError("Необходимо переопределить метод") ==== Декораторы классов ==== Аналогично декораторам функций\\ def deco(C): ... return C @deco class MyClass: def __init__(self, value): self.v= value c= myClass(5) print(c.v)