Начало > В глубь языка Python > Средства объектно-ориентированного программирования > Определение классов | << >> | ||||
В глубь языка Python Для программистов |
Python имеет полноценную поддержку объектно-ориентированного программирования: вы божете определять собственные классы, наследоваться от встроенных и собственных классов, создавать экземпляры определенных вами классов.
Определять классы в языке Python просто. Как и для функций, для классов нет отдельного определения интерфейса. Определения класса в языке Python начинается с зарезервированного слова class и следующего за ним имени класса. Технически, это все что требуется, так как класс совсем необязательно должен быть производным от другого класса.
class foo: pass
Инструкция pass в Python ведет себя аналогично пустым фигурным скобкам ({}) в Java и C. |
Конечно, в реальных программах большинство классов будут производными от других классов и будут определять собственные атрибуты и методы. Но, как вы уже увидели, нет ничего, что класс обязательно должен иметь, кроме имени. В частности, программистам на C++ может показаться странным, что классы в языке Python не имеют явных конструкторов и деструкторов. В классах языка Python есть нечто? похожее на конструктор — метод __init__.
Пример 3.6. Определение класса FileInfo
from UserDict import UserDict class FileInfo(UserDict):
В языке Python родительские классы просто перечисляются в скобках сразу после имени класса. В данном случае класс FileInfo наследуется от класса UserDict (который был проимпортирован из модуля UserDict). UserDict — класс, который ведет себя аналогично словарю, позволяя от него наследоваться и изменять или дополнять его поведение. (Существуют аналогичные классы UserList и UserString, позволяющие определить класс, производный от списка и строки.) Здесь есть немного черной магии, которую мы раскроем позже в этой главе, когда будем подробнее исследовать класс UserDict. |
В языке Python родительские классы просто перечисляются в скобках после имени. Для этого не нужно использовать специальное ключевое слово, такое как extends в Java. |
Хотя я не буду буду рассказывать об этом подробно, Python поддерживает множественное наследование. В скобках после имени класса вы можете пересислить через запятую столько родительских классов, сколько вам нужно. |
Пример 3.7. Инициализация класса FileInfo
class FileInfo(UserDict): "хранит метаинформацию о файле" def __init__(self, filename=None):
Для классов можно (и желательно) определять строку документации, также как для модулей и функций. | |
Метод __init__ вызывается сразу после создания экземпляра класса. Соблазнительно, но не правильно называть этот метод конструктором. Соблазнительно, потому что он выглядит как конструктор (принято, чтобы __init__ был первым методом, определенным в классе), ведет себя как коструктор (это перый кусок кода, вызываемый в созданном экземпляре класса) и даже называется как коструктор. Неправильно, так как к тому времени, когда вызывается метод __init__, объект уже создан и вы имеете ссылку на созданный экземпляр класса. Но метод __init__ — это самое близкое к конструктору, из того что есть в языке Python. | |
Первым аргументом каждого метода класса, включая __init__, всегда является текущий экземпляр класса. Общепринято всегда называть этот аргумент self. В методе __init__ self ссылается на только что созданный объект, в других методах — на экземпляр класса, для которого метод вызывается. Хотя и необходимо явно указывать self при определении метода, вы его не указываете, когда вызываете метод; Python добавит его автоматически. | |
Метод __init__ может иметь несколько аргументов. Аргументы могут иметь значения по умолчанию, что сделает их необязательными. В данном случае аргумент filename имеет значение по умолчанию None. |
Первый аргумент метода класса (ссылка на текущий экземпляр) принято называть self. Этот аргумент играет роль зарезервированного слова this в C++ и Java, но self не является зарезервированным словом — просто соглашение. Несмотря на это, не стоит называть его иначе, чем self. |
Пример 3.8. Тело класса FileInfo
class FileInfo(UserDict): "хранит метаинформацию о файле" def __init__(self, filename=None): UserDict.__init__(self) self["name"] = filename
В определении методов необходимо явно указывать self в качестве первого аргумента любого метода, включая __init__. При вызове метода базового класса также необходимо включать self в список аргументов. Но при вызове метода извне аргумент self не указывается, а подставляется интерпретатором автоматически. Подозреваю, что сначала это сбивает с толку и может показаться непоследовательным, так как вы еще не узнали о разнице между связаннымы и несвязанными методами. |
Вот так. Понимаю, что здесь многое нужно запомнить, но вы быстро наловчитесь. Все классы в языке Python работают одинаково, так что изучив один, вы узнаете обо всех. Вы можете забыть обо всем остальном, но одно правило стоит запомнить (иначе, обещаю, вы когда-нибудь запутаетесь):
Метод __init__ не является обязательным, но если вы его определяете, то не забудть вызвать методы __init__ базовых классов. Это правило верно и в более широком смысле: если производный класс хочет расширить поведение базового, то он должен в нужное время вызвать соответствующий метод базового класса с необходимыми ему аргументами. |
Дополнительная литература
Импортирование модулей инструкцией from module import | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Создание экземпляров классов |
Copyright © 2023 Mark Pilgrim, diveintopython.org |