Методы — Python: Введение в ООП
Имена атрибутов класса могут указывать на функции. Такие функции называются методами. Вы уже сталкивались с методами, когда работали со встроенными структурами данных. Давайте же объявим класс и метод в нем:
class C: def add(x, y): return x + y C.add # C.add(4, 5) # 9
Здесь C.add — обычная функция, о чем нам и говорит интерпретатор. Но сами по себе обычные функции, помещенные в класс, не так интересны: те же функции мы можем группировать и в модулях. Более того, обычные функции стоит объявлять именно в модулях.
Методы же нужны для того, чтобы работать с данными объектов класса. Но для этого методы должны быть связаны (bound).
Связанные методы
Вспомните, метод list.append ( list — это класс, помним и это) модифицирует именно объект списка. Посмотрим на этот метод поближе:
l = [] list.append(l, 42) l # [42]
Я вызвал метод класса, как обычную функцию и передал первым аргументом объект списка. Метод изменил переданный список. Но ведь раньше мы вызывали этот метод в виде l.append(42) ! Так вот l.append это связанная версия метода list.append : метод связан с конкретным объектом списка и знает, что именно его он должен модифицировать!
Определим класс с атрибутом и методом, затем получим экземпляр класса и посмотрим на вывод REPL для разных версий метода (связанной и не связанной):
class Foo: def bar(): pass x = Foo() x # Foo.bar # x.bar # >
Foo.bar — это не связанный метод, то есть обычная функция. А вот x.bar уже связан («bound») с объектом x : обратите внимание на одну и ту же строку » » — так Python отображает объект x .
Но как метод получает доступ к связанному объекту, спросите вы? В Python методы получают ссылку на связанный объект в качестве первого аргумента. А называть этот аргумент принято именем «self». Вот пример метода, использующего данные объекта:
class Person: name = 'Noname' def greet(self): print('Hello, ' + self.name + '!') bob = Person() bob.name = 'Bob' bob.greet() # => Hello, Bob! alice = Person() alice.greet() # => Hello, Noname!
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Чем метод отличается от функции в Python?
Метод по сути это та же функция, но так как она определена внутри класса, и первым её аргументом является self , то она становится связанным методом bound method , получившим доступ к атрибутам связанного объекта (экземпляра класса).
# Обычная функция: def greet(name): print(f'Hello, name>') class Person: # Инициализатор класса, требующий присваивать значение атрибута name при инстанцировании объекта def __init__(self, name): self.name = name # Связанный метод, имеющий доступ к атрибуту name: def greet(self): print(f'Hello , self.name>. ') bob = Person('Bob') # Вызов связанного метода класса: bob.greet() # => Hello , Bob. # Вызов функции, не имеющий доступа к атрибутам объекта: greet(bob) # => Hello, # Вызов обычной функции, которой можно передать любое значение: greet('Bob') # => Hello, Bob greet(23) # => Hello, 23 greet('apple') # => Hello, apple
09 декабря 2022
В отличие от функции, метод узко специализирован и может быть применен только к объектам, которые его поддерживают. Например, метод списков append() может быть применен только к ним. Применение данного метода к другим объектам, которые его не поддерживают (строки или кортежи) вызовет ошибку. Но есть и такие методы, которые хорошо работают с несколькими типами объектов, например метод count() может применяться к строкам, спискам или кортежам
Что такое методы в Python
Ваня — ученик 4А класса. Ваня очень любит печеньки.
У строк есть методы (см. методы строк). Воспользуемся методом .replace() :
Код
print("Ваня — ученик 4А класса. Ваня очень любит печеньки.".replace("Ваня", "Игорь"))
Игорь — ученик 4А класса. Игорь очень любит печеньки.
В строке про Ваню его имя заменилось на “Игорь”.
Давайте разбираться
Методы похожи на функции. Они тоже пишутся со скобочками и в них тоже передаются аргументы. Отличаются они тем, что привязаны к объекту, для которого вызываются. В примере выше .replace() привязан к строке «Ваня — ученик 4А класса. Ваня очень любит печеньки.» . Он заменил в этой строке все кусочки, где написано “Ваня” на “Игорь”.
Методы придумали для того, чтобы привязывать функции к типу данных. Вы уже работали со строками и числами. Забегая вперёд, есть и другие типы данных: списки, множества, даже картинки! Функция замены кусочков строки на другие нужна только для строк, с числами такое не делают. Функция округления нужна только для чисел, строку нельзя “округлить”. Чтобы не гадать какая функция для каких типов данных — придумали методы, привязанные к этим типам точкой.
Если всё ещё не понятно:
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.
Метод объекта/экземпляра класса в Python
Методы — это функции, вызываемые с использованием точечной нотации. Если обратится к методу (функции, определенной в пространстве имен класса) через экземпляр, то получим специальный объект: объект привязанного метода (также называемого методом экземпляра). При вызове он добавляет аргумент self в список аргументов.
Обычно метод вызывается сразу после его привязки:
class MyClass: """Простой пример класса""" i = 12345 def f(self): return 'hello world' x = MyClass() x.f() # 'hello world'
В примере с классом MyClass метод экземпляра класса x.f() возвращает строку «hello world». Нет необходимости вызывать метод сразу, x.f — это объект метода класса и его можно сохранить и вызвать позже. В примере ниже — бесконечный цикл, который будет продолжать печатать «hello world».
xf = x.f while True: print(xf())
Что именно происходит при вызове метода? Заметили, что x.f() был вызван без аргумента? Хотя в определение функции f() был указан один аргумент self . Python всегда вызывает исключение, когда функция, требующая аргумента, вызывается без него, даже если аргумент фактически не используется…
Особенность методов заключается в том, что объект экземпляра передается в качестве первого аргумента self функции. В примере вызов x.f() в точности эквивалентен вызову MyClass.f(x) . В общем случае вызов метода со списком из n аргументов эквивалентен вызову соответствующей функции со списком аргументов, который создается путем вставки объекта экземпляра метода перед первым аргументом.
При ссылке на атрибут экземпляра, не являющийся атрибутом данных, выполняется поиск экземпляра класса. Если имя обозначает допустимый атрибут класса, который является объектом функции, объект метода создается путем упаковки указателей объекта экземпляра и объекта функции, только что найденных вместе в абстрактном объекте: это объект метода. Когда объект метода вызывается со списком аргументов, новый список аргументов создается из экземпляра класса и списка аргументов этого класса, а объект функции вызывается с этим новым списком аргументов.
Первый аргумент метода называется self . Это не более чем соглашение: имя self не имеет абсолютно никакого особого значения для Python. Обратите внимание, что не следуя соглашению, ваш код может быть менее читаемым для других программистов Python и также может быть написана некая программа для просмотра классов, которая будет основываться на этом соглашении.
Любой функциональный объект, являющийся атрибутом класса, определяет метод для экземпляров этого класса. Нет необходимости в том, чтобы определение функции было текстуально заключено в определение класса: присвоение объекта функции локальной переменной в классе также нормально.
# Функция, определенная вне класса def f1(self, x, y): return min(x, x+y) class C: f = f1 def g(self): return 'hello world' h = g
Обратите внимание, что эта практика обычно только запутывает читателя программы. Теперь f , g и h — это все атрибуты класса C , которые относятся к функциональным объектам, и, следовательно, все они являются методами экземпляров класса C . Метод h точно эквивалентны g .
Методы могут вызывать другие методы, используя атрибуты метода собственного аргумента:
class Bag: def __init__(self): self.data = [] def add(self, x): self.data.append(x) def addtwice(self, x): self.add(x) self.add(x)
Методы могут ссылаться на глобальные имена так же, как обычные функции. Глобальной областью видимости, связанной с методом, является модуль, содержащий его определение. Класс никогда не используется в качестве глобальной области видимости. Хотя редко встречаются веские причины для использования глобальных данных в методе, существует много законных вариантов использования глобальной области видимости. Функции и модули, импортированные в глобальную область, могут использоваться методами, а также функциями и классами, определенными в нем. Обычно класс, содержащий метод, сам определяется в этой глобальной области видимости.
Поддержка получения произвольных атрибутов методами.
Связанные методы имеют два специальных атрибута, доступных только для чтения: m.__ self__ — это объект, с которым работает метод, и m.__func__ — это функция, реализующая метод. Вызов m(arg-1, arg-2, . arg-n) полностью эквивалентен вызову m.__func__(m.__self__, arg-1, arg-2, . arg-n) .
Как и объекты функций, связанные объекты методов поддерживают получение произвольных атрибутов. Однако, поскольку атрибуты метода фактически хранятся в базовом объекте функции ( meth.__func__ ), то установка атрибутов метода для связанных методов запрещена. Попытка установить атрибут в методе приводит к возникновению исключения AttributeError . Чтобы установить атрибут метода, необходимо явно установить его для базового объекта функции:
>>> class C: . def method(self): . pass . >>> c = C() >>> c.method.whoami = 'my name is method' # can't set on the method # Traceback (most recent call last): # File "", line 1, in # AttributeError: 'method' object has no attribute 'whoami' >>> c.method.__func__.whoami = 'my name is method' >>> c.method.whoami # 'my name is method'
- ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
- Пространство имен и область видимости в классах
- Определение классов
- Объект класса и конструктор класса
- Создание экземпляра класса
- Метод экземпляра класса
- Что такое метод класса и зачем нужен
- Что такое статический метод в классах Python и зачем нужен
- Атрибуты класса и переменные экземпляра класса
- Кэширование методов экземпляра декоратором lru_cache
- Закрытые/приватные методы и переменные класса Python
- Наследование классов
- Множественное наследование классов
- Абстрактные классы
- Перегрузка методов в классе Python
- Что такое миксины и как их использовать
- Класс Python как структура данных, подобная языку C
- Создание пользовательских типов данных
- Специальные (магические) методы класса Python
- Базовая настройка классов Python магическими методами
- Настройка доступа к атрибутам класса Python
- Дескриптор класса для чайников
- Протокол дескриптора класса
- Практический пример дескриптора
- Использование метода .__new__() в классах Python
- Специальный атрибут __slots__ класса Python
- Специальный метод __init_subclass__ класса Python
- Определение метаклассов metaclass
- Эмуляция контейнерных типов в классах Python
- Другие специальные методы класса
- Как Python ищет специальные методы в классах
- Шаблон проектирования Фабрика и его реализация