Начало > В глубь языка 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 не указывается, а подставляется интерпретатором автоматически. I am aware that this is confusing at first; it's not really inconsistent, but it may appear inconsistent because it relies on a distinction (between bound and unbound methods) that you don't know about yet. |
Whew. I realize that's a lot to absorb, but you'll get the hang of it. All Python classes work the same way, so once you learn one, you've learned them all. If you forget everything else, remember this one thing, because I promise it will trip you up:
__init__ methods are optional, but when you define one, you must remember to explicitly call the ancestor's __init__ method. This is more generally true: whenever a descendant wants to extend the behavior of the ancestor, the descendant method must explicitly call the ancestor method at the proper time, with the proper arguments. |
Further reading
Импортирование модулей инструкцией from module import | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Instantiating classes |
Copyright © 2000, 2001, 2002 Марк Пилгрим Copyright © 2001, 2002 Перевод, Денис Откидач |