Using function in class python

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

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

От редакции Pythonist: предлагаем также почитать статьи «Классы в Python» и «Переменные класса и экземпляра в Python».

Приведенный ниже пример класса с именем Greetings принимает имя и возвращает приветствие человеку, вызывающему этот класс.

class Greetings: def good_morning(name): print(f'Good morning ') def good_afternoon(name): print(f'Good afternoon ') def good_evening(name): print(f'Good evening ') 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 ') def good_afternoon(name): print(f'Good afternoon ') def good_evening(name): print(f'Good evening ') 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

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

Когда мы создаем экземпляр класса, то первым аргументом, передаваемым функции, является сам этот экземпляр. Таким образом, причина, по которой мы получаем ошибку 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 ") print(f"Student age: ") print(f"Major: ") s = Student('Sally' , 'Harris', 20, 'Biology') s.profile()
Student name Sally Harris Student age: 20 Major: Biology

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

Читайте также:  Python command line execute string

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

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 ") print(f"Student age: ") print(f"Major: ") def enrol(self, course): self.courses.append(course) print(f"enrolled in ") def show_courses(self): print(f" 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 ") print(f"Student age: ") print(f"Major: ") def enrol(self, course): self.courses.append(course) print(f"enrolled in ") def show_courses(self): print(f" 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

Classes can be created as simply a collection of functions. The functions can be defined within the class exactly the same way that functions are normally created. In order to call these functions we need to call it from the class. So the example class called Greetings below takes a name and returns a greeting to the person calling the class.

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

Common Mistake

Although the class above behaves as we would expect. Let’s take the exact same class and add an __init__. See this article if you don’t know what the __init__ is.

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

We have created an instance of the Greetings class named g. If we try to call the functions we defined within the class as follows:

TypeError: good_afternoon() takes 1 positional argument but 2 were given

It may not immediately be clear as to why this is happening. The TypeError returned above indicates that we have passed 2 arguments to the function, when it appears we have only passed one. Let’s try calling it without a name to see what happens:

 g.good_afternoon() # out: Good afternoon

What is going on here?

Читайте также:  Compressed references in java

When we create an instance of a class the first argument passed to the function is the instance itself. So the reason we are getting the TypeError is that the way Python is reading the g.good_afternoon(‘John’) function is g.good_afternoon(g, ‘John’) although this may seem confusing, it will become clear in the next section why this happens.

Instance Methods

Taking a new example class called Student, which takes a first name, last name, age and major.

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 ") print(f"Student age: ") print(f"Major: ") s = Student('Sally' , 'Harris', 20, 'Biology') s.profile() 
Out: Student name Sally Harris Student age: 20 Major: Biology

When creating instance methods we must pass the self keyword, this takes care of the issue of the instance being passed to functions as the first argument. Let’s build on the current class and add enrollment functionality to show the ability of instance methods to interact with attributes.

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 ") print(f"Student age: ") print(f"Major: ") def enrol(self, course): self.courses.append(course) print(f"enrolled in ") def show_courses(self): print(f" 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 

All of the methods above have been bound to the instance (we named this instance s), we can check this by using the dir keyword on the instance to see all the attributes and methods bound to s.

Out: ['__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']

We can add a mix of instance bound functions and normal functions as defined at the beginning of the document. Below we add a method that prints the current academic year.

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 ") print(f"Student age: ") print(f"Major: ") def enrol(self, course): self.courses.append(course) print(f"enrolled in ") def show_courses(self): print(f" 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]) >")

However, we will still get an error if we try to call this new function from an instance, as we have established that calling methods/ functions from an instance always passes the instance itself in as the first argument. So If we wanted to call this academic year function we can do so as follows:

Student.academic_year() # returns: Current academic year is 2020/2019

A better way to handle this will be the topic of the next article on class & static methods.

Читайте также:  Cannot find symbol java annotation

Summary

— When calling a function from a class the syntax is ClassName.FunctionName()

— When calling a function bound to an instance of a class, the first argument passed in to the function is the instance itself. These are known as methods

— To access and call a method correctly we should pass self in as the first argument when writing the code for the method.

— These methods allow us to interact with attributes associated with the instance / class.

Источник

Оцените статью