Share This
Связаться со мной
Крути в низ
Categories
//Добавление функций в классы Python

Добавление функций в классы Python

25.03.2023Category : Python

Классы в Python могут создаваться просто как коллекции функций. Функции могут быть определены внутри класса обычным образом, так же как и внутри любой программы. А вот для вызова такой функции нужно действовать через данный класс. Таким образом, приведенный ниже пример класса с именем Greetings принимает имя и возвращает приветствие человеку, вызывающему этот класс.

class Greetings:     def good_morning(name):         print(f'Good morning {name}')              def good_afternoon(name):         print(f'Good afternoon {name}')              def good_evening(name):         print(f'Good evening {name}')                   Greetings.good_afternoon('John') Greetings.good_morning('Peter') Greetings.good_evening('Jane') 

Результат:

Good afternoon John Good morning Peter Good evening Jane

Распространенная ошибка

Пока данный класс ведет себя так как мы и планировали. Но давайте теперь добавим в него магический метод __init__.

class Greetings:          def __init__(self):         pass          def good_morning(name):         print(f'Good morning {name}')              def good_afternoon(name):         print(f'Good afternoon {name}')              def good_evening(name):         print(f'Good evening {name}')                   g = Greetings()

Мы также создали экземпляр класса Greeting и поместили его в переменную g. Если мы попытаемся вызвать функцию класса как в прошлый раз, только через экземпляр класса, то получим следующую ошибку:

g.good_afternoon('John')  # Результат: # TypeError: good_afternoon() takes 1 positional argument but 2 were given

Может быть не вполне понятно, что сейчас произошло. Возвращенная выше ошибка TypeError сообщает, что мы передали функции 2 аргумента вместо одного. А с виду кажется, что был передан только один аргумент. Чтобы понять, что произошло, давайте попробуем вызвать нашу функцию вообще без аргумента:

 g.good_afternoon()  # Результат: # Good afternoon <__main__.Greetings object at 0x00000284083D1B88>

Что же тут происходит?

Когда мы создаем экземпляр класса, то первым аргументом, передаваемым функции, является сам этот экземпляр. Таким образом, причина, по которой мы получаем ошибку TypeError, заключается в том, что Python считывает функцию g.good_afternoon(‘John’) как g.good_afternoon(g, ‘John’). Это может показаться запутанным, но в следующих секциях будет ясно почему такое происходит.

Методы экземпляров класса

Рассмотрим новый пример класса под названием Student, который принимает в качестве параметров имя, фамилию, возраст и специальность.

class Student:     def __init__(self, first, last, age, major):         self.first = first          self.last = last         self.age = age         self.major = major          def profile(self):         print(f"Student name {self.first + ' ' + self.last}")         print(f"Student age: {self.age}")         print(f"Major: {self.major}")                    s = Student('Sally' , 'Harris', 20, 'Biology')          s.profile()

Результат:

Student name Sally Harris Student age: 20 Major: Biology

При определении методов экземпляра мы должны передавать в качестве первого аргумента ключевое слово self. Это решает проблему передачи экземпляра класса функциям в качестве первого аргумента. Давайте создадим текущий класс и добавим функциональность регистрации, чтобы показать способность методов экземпляра класса взаимодействовать с атрибутами.

class Student:     def __init__(self, first, last, age, major):         self.first = first          self.last = last         self.age = age         self.major = major         self.courses = []           def profile(self):         print(f"Student name {self.first + ' ' + self.last}")         print(f"Student age: {self.age}")         print(f"Major: {self.major}")                       def enrol(self, course):         self.courses.append(course)         print(f"enrolled {self.first} in {course}")                   def show_courses(self):         print(f"{self.first + ''  + self.last} is taking the following courses")         for course in self.courses:             print(course)                           s = Student('Sally' , 'Harris', 20, 'Biology')          s.enrol('Biochemistry I')     # enrolled Sally in Biochemistry I  s.enrol('Literature')     # enrolled Sally in Literature  s.enrol('Mathematics') # enrolled Sally in Mathematics  s.show_courses() # SallyHarris is taking the following courses # Biochemistry I # Literature # Mathematics 

Все вышеперечисленные методы были привязаны к экземпляру класса Student, который мы сохранили в переменную s. Мы можем проверить это, используя ключевое слово dir для нашего экземпляра класса, чтобы увидеть все атрибуты и методы, привязанные к нему.

dir(s)  # Результат: ['__class__',  '__delattr__',  '__dict__',  '__dir__',  '__doc__',  '__eq__',  '__format__',  '__ge__',  '__getattribute__',  '__gt__',  '__hash__',  '__init__',  '__init_subclass__',  '__le__',  '__lt__',  '__module__',  '__ne__',  '__new__',  '__reduce__',  '__reduce_ex__',  '__repr__',  '__setattr__',  '__sizeof__',  '__str__',  '__subclasshook__',  '__weakref__',  'age',  'courses',  'enrol',  'first',  'last',  'major',  'profile',  'show_courses']

В рамках класса мы можем сочетать функции, привязанные к экземплярам класса и обычные функции, которые мы привели в начале данной статьи. Давайте ниже добавим функцию, которая будет выводить на экран текущий учебный год.

import datetime as dt  class Student:     def __init__(self, first, last, age, major):         self.first = first          self.last = last         self.age = age         self.major = major         self.courses = []           def profile(self):         print(f"Student name {self.first + ' ' + self.last}")         print(f"Student age: {self.age}")         print(f"Major: {self.major}")                       def enrol(self, course):         self.courses.append(course)         print(f"enrolled {self.first} in {course}")                   def show_courses(self):         print(f"{self.first + ''  + self.last} is taking the following courses")         for course in self.courses:             print(course)               def academic_year():         now = dt.datetime.now()         s = now.year, now.year -1          print(f"Current academic year is { str(s[0]) + '/' + str(s[1]) }")

Однако мы все равно получим ошибку, если попытаемся вызвать эту новую функцию из экземпляра класса, так как вызов методов/функций из экземпляров класса всегда передает сам экземпляр класса в качестве первого аргумента. Таким образом, если мы хотим вызвать функцию academic_year(), это можно сделать это следующим образом:

Student.academic_year()  # Результат: Current academic year is 2020/2019

Заключение

При вызове функции из класса используется синтаксис ClassName.FunctionName().

При вызове функции, привязанной к экземпляру класса, первым аргументом, передаваемым функции, является сам экземпляр класса. Такие функции также называют методами.

Чтобы метод правильно работал, мы должны при его написании в качестве первого аргумента указать ключевое слово self.

Данные методы дают нам возможность взаимодействовать с атрибутами, связанными с экземплярами класса.

Перевод статьи Adding Functions to Python Classes.

  • 0 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close