Любой файл с кодом, является модулем. Импортированный модуль может содержать программу на С.
Запускаемый модуль всегда называется main, доступно через атрибут «name«
import <название модуля> [as <Псевдоним>]
Название без расширения и т.д., создается одноименный идентификатор, наравне с переменными, через который в дальнейшем и доступно содержимое модуля.
Проверить существование атрибута- hasattr()
Перед выполнением каждый модуль компилируется в байт-код, откомпилированные файлы (*.pyc) хранятся в pycache, их тоже можно импортировать и использовать
Импорт производится при первом вызове, затем кэшируется в sys.modules
import('str') - динамический импорт, название из строки (переменной)
Для импортирования только определенных идентификаторов
from <модуль> import <идентификатор> or (id1, id2 ..)
Хранятся в переменной sys.path. Можно изменять программно- append()
Импортируется один раз, для повторной загрузки ф-я imp.reload()
Папка с модулями, в которой расположен файл инициализации init.py- может быть пустым либо содержать код для первой инициализации при импортировании любого модуля из этого пакета
В отличии от функционального подхода, позволяет описать предметы мира в виде сущностей и организовать связи между ними.
class <Название класса> [(<родит. классы>,...<..>)]: """ Строка документирования """ <Св-ва / Методы>
В момент описания, создается полноценный объект. Выполнение происходит в месте определения а не создания экземпляров
Всем методам, обязательно, первым параметром передается ссылка на экземпляр класса (self), либо вызывать ф-ю из объекта
Все атрибуты и методы являются public, можно закрывать костылями
Атрибуты классу (не объекту а именно классу) можно создавать в коде, динамически (собсна функции выше)
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
Конструктор/Деструктор (в скриптовой специфике 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)