Методы классов. Параметр self
Мы продолжаем изучать ООП языка Python. Как я говорил на первом занятии, класс может содержать свойства (данные) и методы (функции). Благодаря методам внутри класса можно реализовывать самые разные алгоритмы, то есть методы – это действия. Именно поэтому, в названиях методов используют глаголы, например:
set_value, get_param, start, stop, и т.п.
В то время как именами свойств (данных) выступают существительные:
color, size, x, y, и т.п.
Рекомендуется придерживаться этого простого правила.
Давайте, для примера объявим метод set_coords в классе Point, который будет просто выводить в консоль сообщение «вызов метода set_coords»:
class Point: color = 'red' circle = 2 def set_coords(self): print("вызов метода set_coords")
Здесь сразу бросается в глаза вот этот параметр self, который автоматически прописывает интегрированная среда. Зачем он здесь, если мы пока ничего не собираемся передавать этому методу? Давайте его уберем! Пока никаких проблем не возникло. Мало того, мы можем его вызвать из класса Point:
Point.set_coords()
и все будет работать без ошибок. Здесь мы видим, как вызываются методы класса. Все довольно очевидно. Записываем имя класса (Point), и через точку указываем имя метода. В конце обязательно прописываем круглые скобки, так как это оператор вызова функций. И, так как метод – это функция класса, то для вызова метода используется тот же оператор, что и для вызова функций.
В результате, мы получили класс, в котором два свойства и один метод. Далее, создадим экземпляр этого класса:
pt = Point()
И, как мы с вами говорили, через объект pt можно обращаться ко всем атрибутам класса Point, в том числе и к методу set_coords:
pt.set_coords
Этот атрибут ссылается на объект-функцию, которую мы определили в классе Point. Попробуем ее вызвать:
pt.set_coords()
Видим ошибку, что в метод set_coords при вызове передается один аргумент, а он у нас определен без параметров. Дело в том, что когда мы вызываем методы класса через его объекты, то интерпретатор Python автоматически добавляет первым аргументом ссылку на объект, из которого этот метод вызывается.

Поэтому, если мы хотим внутри класса определить метод, который можно было бы вызывать из его экземпляров, то дополнительно прописывается первый параметр, обычно, с именем self:
class Point: color = 'red' circle = 2 def set_coords(self): print("вызов метода set_coords " + str(self))
Еще раз, параметр self будет ссылаться на экземпляр класса, из которого вызывается метод. Зачем это надо? Сейчас узнаете. После этого дополнения мы уже не сможем вызвать данный метод через класс без указания первого аргумента:
Point.set_coords()
но можем через его объекты:
pt.set_coords()
То есть, когда метод вызывается через класс, то Python автоматически не подставляет никаких аргументов. А когда вызов идет через экземпляры класса, то первый аргумент – это всегда ссылка на экземпляр. Данный момент нужно знать и помнить.
Но мы все же можем вызвать метод set_coords и через класс, если явно передадим ссылку на объект pt, следующим образом:
Point.set_coords(pt)
Именно это на автомате делает Python, когда вызов осуществляется через объекты классов.
Так зачем понадобилось такое поведение? Дело в том, что метод класса – это тоже его атрибут и когда создаются экземпляры класса, то метод становится общим для всех объектов и не копируется в них. Фактически, только благодаря параметру self мы «знаем» какой объект вызвал данный метод и можем организовать с ним обратную связь.
Например, пусть метод set_coords задает координаты точек для текущего объекта. Тогда, мы пропишем в нем два дополнительных параметра и через self в самом экземпляре класса создадим (либо переопределим) два свойства:
class Point: color = 'red' circle = 2 def set_coords(self, x, y): self.x = x self.y = y
В результате, при вызове метода:
pt.set_coords(1, 2) print(pt.__dict__)
в объекте pt будут созданы два свойства x, y со значениями 1 и 2. Вот для чего нужен этот параметр self. Если в программе создать еще один объект:
pt2 = Point()
и через него вызвать тот же самый метод:
pt2.set_coords(10, 20) print(pt2.__dict__)
То увидим, что свойства x, y со значениями 10 и 20 были созданы только в нем (в его пространстве имен) и никак не связаны с координатами другого объекта pt или классом Point. То есть, через self мы работаем с конкретным объектом, из которого был вызван данный метод.
Конечно, в классах мы можем прописывать произвольное количество методов. Например, определим еще один, который будет возвращать координаты точки в виде кортежа значений:
class Point: color = 'red' circle = 2 def set_coords(self, x, y): self.x = x self.y = y def get_coords(self): return (self.x, self.y)
И ниже в программе можем вызвать его:
print(pt.get_coords())
Интересно, что так как имя метода – это атрибут класса, то мы можем обратиться к нему через знакомую нам уже функцию:
res = getattr(pt, 'get_coords') print(res)
Видим, что это ссылка на объект-функцию. А раз так, то ничто нам не мешает ее здесь вызывать:
print(res())
Конечно, так делают очень редко. Обычно используют синтаксис через точку. Я привел это, чтобы еще раз подчеркнуть, что имена методов – это те же самые атрибуты, просто они ведут не на данные, а на функции. Во всем остальном они схожи с атрибутами-данными класса.
Заключение
Итак, на этом занятии вы должны были узнать, как определяются простые методы класса, за что отвечает параметр self и как происходит обращение к методам и их вызов. Если все это понятно, то смело переходите к следующему занятию, где мы продолжим эту тему.
Видео по теме

Концепция ООП простыми словами

#1. Классы и объекты. Атрибуты классов и объектов

#2. Методы классов. Параметр self

#3. Инициализатор __init__ и финализатор __del__

#4. Магический метод __new__. Пример паттерна Singleton

#5. Методы класса (classmethod) и статические методы (staticmethod)

#6. Режимы доступа public, private, protected. Сеттеры и геттеры

#7. Магические методы __setattr__, __getattribute__, __getattr__ и __delattr__

#8. Паттерн Моносостояние

#9. Свойства property. Декоратор @property

#10. Пример использования объектов property

#11. Дескрипторы (data descriptor и non-data descriptor)

#12. Магический метод __call__. Функторы и классы-декораторы

#13. Магические методы __str__, __repr__, __len__, __abs__

#14 Магические методы __add__, __sub__, __mul__, __truediv__

#15. Методы сравнений __eq__, __ne__, __lt__, __gt__ и другие

#16. Магические методы __eq__ и __hash__

#17. Магический метод __bool__ определения правдивости объектов

#18. Магические методы __getitem__, __setitem__ и __delitem__

#19. Магические методы __iter__ и __next__

#20. Наследование в объектно-ориентированном программировании

#21. Функция issubclass(). Наследование от встроенных типов и от object

#22. Наследование. Функция super() и делегирование

#23. Наследование. Атрибуты private и protected

#24. Полиморфизм и абстрактные методы
#25. Множественное наследование

#26. Коллекция __slots__

#27. Как работает __slots__ с property и при наследовании

#28. Введение в обработку исключений. Блоки try / except

#29. Обработка исключений. Блоки finally и else

#30. Распространение исключений (propagation exceptions)

#31. Инструкция raise и пользовательские исключения

#32. Менеджеры контекстов. Оператор with

#33. Вложенные классы

#34. Метаклассы. Объект type

#35. Пользовательские метаклассы. Параметр metaclass

#36. Метаклассы в API ORM Django

#37. Введение в Python Data Classes (часть 1)

#38. Введение в Python Data Classes (часть 2)

#39. Python Data Classes при наследовании
© 2024 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Как вызвать метод из родительского класса python?
Для вызова метода из родительского класса в Python есть два способа:
- Явное обращение к методу предка
- Функция super()
class Counter: def __init__(self): self.value = 0 def inc(self): self.value += 1 def dec(self): self.value -= 1 # Создаем класс-потомок, при вызове inc увеличивающих значение дважды # Вариант 1 - с прямым обращением к предку: class DoubleCounter(Counter): def inc(self): Counter.inc(self) # явно обращаемся к методу класса предка Counter.inc(self) # и передаем ссылку на экземпляр # Вариант 2 - с применением функции super(): class DoubleCounter(Counter): def inc(self): super().inc() super().inc() num = DoubleCounter() num.value # 0 num.inc() # В обоих случаях, наследованный метод inc() будет работать одинаково num.value # 2
Функция super() названа в честь названия класса-предка: «superclass». Потому что благодаря ей мы получаем ссылку на атрибут предка и заменяем обращение self , создавая таким образом связанный с текущим классом метод, который будет полноценной «оригинальной версией» из класса-предка. При чем если предок сменится, то super в описании класса учтет изменения, и мы получим доступ к поведению нового предка.
Вызов метода класса в другом методе этого же класса
При попытке вызвать метод: delFromArray(objects,5) , говорит, что нет такой функции. Как правильно это делается в питоне?
Отслеживать
6,399 4 4 золотых знака 35 35 серебряных знаков 57 57 бронзовых знаков
задан 31 мар 2017 в 11:25
69 1 1 золотой знак 1 1 серебряный знак 11 11 бронзовых знаков
self.delFromArray(objects,5)
31 мар 2017 в 11:53
либо вынести функцию def delFromArray(arr,count) за пределы класса
31 мар 2017 в 11:57
Спасибо, дружище. Ответь полноценно, отмечу как ответ на мой вопрос. Все работает! первый вариант лучше подходит)
31 мар 2017 в 11:59
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
delFromArray(arr,count) — это вызов внешней функции, которая определена вне класса. Чтобы внутри класса вызвать один из методов самого класса нужно добавлять к вызову self . Т.е. self.delFromArray(arr,count) . Так как данный метод все-таки определен внутри класса, то его стоит сделать статическим:
@staticmethod def delFromArray(arr,count): pass
Как сделать вызов функции внутри класса php?
Для вызова функции внутри класса используется ключевое слово self или $this-> . Например:
class MyClass public function helloWorld() echo 'Hello World!'; > public function callHelloWorld() self::helloWorld(); > > $myClass = new MyClass(); $myClass->callHelloWorld(); // => Hello World!
class MyClass public function helloWorld() echo 'Hello World!'; > public function callHelloWorld() $this->helloWorld(); > > $myClass = new MyClass(); $myClass->callHelloWorld(); // => Hello World!