Вложенные классы в python объясняются примерами

Содержание:

Введение в ООП в Python

Python — это мультипарадигмальный язык. Это означает, что он поддерживает различные подходы к программированию.

Одной из наиболее популярных парадигм является создание объектов. Она известна как объектно-ориентированное программирование (ООП).

Объект имеет две характеристики:

  • атрибуты;
  • поведение;

Рассмотрим на примере:

Объект – это попугай:

  • имя, возраст, цвет являются атрибутами;
  • пение, танцы — это поведение;

Концепция ООП в Python направлена ​​на создание кода для многократного использования. Эта концепция также известна как DRY (Don’t Repeat Yourself).

В Python концепция ООП реализует несколько принципов:

Наследование Использование элементов из нового класса без изменения существующего класса.
Инкапсуляция Скрытие приватных элементов класса от других объектов.
Полиморфизм Концепция использования объекта с одинаковым интерфейсом без получения информации о его типе и внутренней структуре.

Instance Attributes

Instance attributes are attributes or properties attached to an instance of a class. Instance attributes are defined in the constructor.

The following example defines instance attributes and in the constructor.

Example: Instance Attributes
Copy

An instance attribute can be accessed using dot notation: , as shown below.

Example:
Copy

You can set the value of attributes using the dot notation, as shown below.

Example:
Copy

You can specify the values of instance attributes through the constructor.
The following constructor includes the name and age parameters, other than the parameter.

Example: Setting Attribute Values
Copy

Now, you can specify the values while creating an instance, as shown below.

Example: Passing Instance Attribute Values in Constructor
Copy

Note:

You don’t have to specify the value of the parameter. It will be assigned internally in Python.

You can also set default values to the instance attributes. The following code sets the default values of the constructor parameters.
So, if the values are not provided when creating an object, the values will be assigned latter.

Example: Setting Default Values of Attributes
Copy

Now, you can create an object with default values, as shown below.

Example: Instance Attribute Default Value
Copy

Visit class attributes vs instance attributes in Python for more information.

ADVERTISEMENT

Конструктор классов

    #defining constructor  
    def __init__(self, personName, personAge):  
        self.name = personName  
        self.age = personAge

Конструктор класса в Python – это первый фрагмент кода, который должен выполняться при создании нового объекта класса.

Прежде всего, конструктор можно использовать для помещения значений в переменные-члены. Вы также можете распечатать сообщения в конструкторе, чтобы убедиться, что объект был создан.

Метод конструктора начинается с def __init__. После этого первым параметром должно быть значение «self», так как он передает ссылку на экземпляр самого класса. Вы также можете добавить дополнительные параметры, как показано в примере. «personName» и «personAge» – это два параметра, которые необходимо отправить, когда должен быть создан новый объект.

Maximum Line Length

Limit all lines to a maximum of 79 characters.

For flowing long blocks of text with fewer structural restrictions
(docstrings or comments), the line length should be limited to 72
characters.

Limiting the required editor window width makes it possible to have
several files open side by side, and works well when using code
review tools that present the two versions in adjacent columns.

The default wrapping in most tools disrupts the visual structure of the
code, making it more difficult to understand. The limits are chosen to
avoid wrapping in editors with the window width set to 80, even
if the tool places a marker glyph in the final column when wrapping
lines. Some web based tools may not offer dynamic line wrapping at all.

Some teams strongly prefer a longer line length. For code maintained
exclusively or primarily by a team that can reach agreement on this
issue, it is okay to increase the line length limit up to 99 characters,
provided that comments and docstrings are still wrapped at 72
characters.

The Python standard library is conservative and requires limiting
lines to 79 characters (and docstrings/comments to 72).

The preferred way of wrapping long lines is by using Python’s implied
line continuation inside parentheses, brackets and braces. Long lines
can be broken over multiple lines by wrapping expressions in
parentheses. These should be used in preference to using a backslash
for line continuation.

Backslashes may still be appropriate at times. For example, long,
multiple with-statements cannot use implicit continuation, so
backslashes are acceptable:

with open('/path/to/some/file/you/want/to/read') as file_1, \
     open('/path/to/some/file/being/written', 'w') as file_2:
    file_2.write(file_1.read())

(See the previous discussion on for further
thoughts on the indentation of such multiline with-statements.)

Another such case is with assert statements.

Работа с классами на Python

Большая часть времени работы программиста — это работа с классами и их экземплярами. Изменим наш предыдущий класс и добавим дополнительные атрибуты, которые сможем в последующем менять при работе с экземплярами класса. 

class Car():
    «»»Описание автомобиля»»»
    def __init__(self, brand, model, years):
        «»»Инициализирует атрибуты»»»
        self.brand = brand
        self.model = model
        self.years = years
        self.mileage = 0

    def get_full_name(self):
        «»»Автомобиль»»»
        name = «Автомобиль {self.brand} {self.model} {self.years}»
         name.

    def read_mileage(self):
        «»»Пробег автомобиля»»»
        («Пробег автомобиля {self.mileage} км.»)

В описание автомобиля есть три атрибута(параметра) это brand, model, years. Также мы создали новый атрибут mileage (пробег) и присвоили ему начальное значение 0. Так как пробег у всех автомобилей разный, в последующем мы сможем изменять этот атрибут. Метод get_full_name будет возвращать полное описание автомобиля. Метод read_mileage будет выводить пробег автомобиля. 

Создадим экземпляр с классом Car и запустим методы:

car_2 = Car(‘audi’, ‘a4’, 2019)
print(car_2.get_full_name())
car_2.read_mileage()

В результате в начале Python вызывает метот __init__() для создания нового экземпляра. Сохраняет название, модель, год выпуска и создает новый атрибут с пробегом равным 0. В итоге мы получим такой результат:

Автомобиль Audi A4 2019
Пробег автомобиля 0 км.

2.1. Прямое изменение значения атрибута

Для изменения значения атрибута можно обратиться к нему напрямую и присвоить ему новое значение. Изменим пробег автомобиля car_2:

car_2 = Car(‘audi’, ‘a4’, 2019)
print(car_2.get_full_name())
car_2.mileage = 38
car_2.read_mileage()

Мы обратились к нашему экземпляру car_2 и связанным с ним атрибутом пробега(mileage) и присвоили новое значение 38. Затем вызвали метод read_mileage() для проверки. В результате мы получим следующие данные. 

Автомобиль Audi A4 2019
Пробег автомобиля 38 км.

2.2. Изменение значения атрибута с использованием метода 

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

class Car():
    «»»Описание автомобиля»»»
    def __init__(self, brand, model, years):
        «»»Инициализирует атрибуты»»»
        self.brand = brand
        self.model = model
        self.years = years
        self.mileage = 0

    def get_full_name(self):
        «»»Автомобиль»»»
        name = «Автомобиль {self.brand} {self.model} {self.years}»
         name.

    def read_mileage(self):
        «»»Пробег автомобиля»»»
        («Пробег автомобиля {self.mileage} км.»)

    def update_mileage(self, new_mileage):
        «»»Устанавливает новое значение пробега»»»
        self.mileage = new_mileage

car_2 = Car(‘audi’, ‘a4’, 2019)
print(car_2.get_full_name())

car_2.read_mileage()
car_2.update_mileage(17100)
car_2.read_mileage()

Вначале выведем текущие показания пробега ( car_2.read_mileage() ). Затем вызовем метод  и передадим ему новое значение пробега ( car_2.update_mileage(17100) ). Этот метод устанавливает пробег 17100. Выведем текущие показания ( car_2.read_mileage() ) и у нас получается:

Автомобиль Audi A4 2019
Пробег автомобиля 0 км.
Пробег автомобиля 17100 км.

2.3. Изменение значения атрибута с приращением

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

def add_mileage(self, km):
        «»»Добавляет пробег»»»
        self.mileage += km

Новый метод add_mileage() получает пробег в км и добавлет его к self.mileage. 

car_2.add_mileage(14687)
car_2.()

Пробег автомобиля 31787 км.

В итоге после вызова метода add_mileage() пробег автомобиля в экземпляре увеличится на 14687 км и станет равным 31787 км. Данный метод мы можем вызывать каждый раз при изменении пробега и передавать новые значение, на которое будет увеличивать основной пробег.

Deleting Attributes and Objects

Any attribute of an object can be deleted anytime, using the statement. Try the following on the Python shell to see the output.

We can even delete the object itself, using the del statement.

Actually, it is more complicated than that. When we do , a new instance object is created in memory and the name c1 binds with it.

On the command , this binding is removed and the name c1 is deleted from the corresponding namespace. The object however continues to exist in memory and if no other name is bound to it, it is later automatically destroyed.

This automatic destruction of unreferenced objects in Python is also called garbage collection.

Deleting objects in Python removes the name binding

Базовые методы перегрузки

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

Sr.No. Метод, описание и пример вызова
1 __init__ (self )

Конструктор (с любыми необязательными аргументами)

Пример вызова: obj = className (args)

2 __del __ (самостоятельно)

Деструктор, удаляет объект

Образец звонка: del obj

3 __repr __ (самостоятельно)

Оцениваемое строковое представление

Пример вызова: repr (obj)

4 __str __ (самостоятельно)

Печатное представление строки

Пример вызова: str (obj)

5 __cmp__ (self, x)

Сравнение объектов

Пример вызова: cmp (obj, x)

Наследование класса в Python

Создавая новые классы не обязательно их создавать с нуля. Новый класс может наследовать свои атрибуты (переменные) и методы (функции принадлежащие классам) от ранее определенного исходного класса ( суперкласса ). Также исходный класс называют родителем, а новый класс — потомком или подклассом. В класс-потомок можно добавлять собственные атрибуты и методы. Напишем новый класс , который будет создан на базе класса :

class Car():
    «»»Описание автомобиля»»»
    def __init__(self, brand, model, years):
        «»»Инициализирует атрибуты brand и model»»»
        self.brand = brand
        self.model = model
        self.years = years
        self.mileage = 0

    def get_full_name(self):
        «»»Автомобиль»»»
        name = f»Автомобиль {self.brand} {self.model} {self.years}»
        return name.title()

    def read_mileage(self):
        «»»Пробег автомобиля»»»
        print(f»Пробег автомобиля {self.mileage} км.»)

    def update_mileage(self, new_mileage):
        «»»Устанавливает новое значение пробега»»»
        self.mileage = new_mileage
    
    def add_mileage(self, km):
        «»»Добавляет пробег»»»
        self.mileage += km

class ElectricCar(Car):
    «»»Описывает электромобиль»»»
    def __init__(self, brand, model, years):
        «»»Инициализирует атрибуты класса родителя»»»
        super().__init__(brand, model, years)
        # атрибут класса-потомка
        self.battery_size = 100

    def battery_power(self):
        «»»Выводит мощность аккумулятора авто»»»
        print(«Мощность аккумулятора {self.battery_size} кВт⋅ч»)

Мы создали класс на базе класса. Имя класса-родителя в этом случае ставится в круглые скобки( class ElectricCar(Car) ). Метод __init__  в классе потомка (подклассе) инициализирует атрибуты класса-родителя и создает экземпляр класса . Функция super() .- специальная функция, которая приказывает Python вызвать метод __init__() родительского класса Car, в результате чего экземпляр ElectricCar получает доступ ко всем атрибутам класса-родителя. Имя super как раз и происходит из-за того, что класс-родителя называют суперклассом, а класс-потомок — подклассом.          

Далее мы добавили новый атрибут и присвоили исходное значение 100. Этот атрибут будет присутствовать во всех экземплярах класса . Добавим новый метод battery_power(), который будет выводить информацию о мощности аккумулятора.         

Создадим экземпляр класса  и сохраним его в переменную tesla_1

tesla_1 = ElectricCar(‘tesla’, ‘model x’, 2021)
print(tesla_1.get_full_name())
tesla_1.battery_power()

При вызове двух методов мы получим:

Автомобиль Tesla Model X 2021
Мощность аккумулятора 100 кВт⋅ч

В новый класс  мы можем добавлять любое количество атрибутов и методов связанных и не связанных с классом-родителем .    

3.1. Переопределение методов класса-родителя

Методы, которые используются в родительском классе можно переопределить в классе-потомке (подклассе). Для этого в классе-потомке определяется метод с тем же именем, что и у класса-родителя. Python игнорирует метод родителя и переходит на метод, написанный в классе-потомке (подклассе). Переопределим метод def get_full_name() чтобы сразу выводилась мощность аккумуляторов. 

class ElectricCar(Car):
    «»»Описывает электромобиль»»»
    def __init__(self, brand, model, years):
        «»»Инициализирует атрибуты класса родителя»»»
        super().__init__(brand, model, years)
        # атрибут класса-потомка
        self.battery_size = 100

    def battery_power(self):
        «»»Выводит мощность аккумулятора авто»»»
        print(«Мощность аккумулятора {self.battery_size} кВт⋅ч»)

    def get_full_name(self):
        «»»Автомобиль»»»
        name = f»Автомобиль {self.brand} {self.model} {self.years} {self.battery_size}-кВт⋅ч »
         name.
 

В результате при запросе полного названия автомобиля Python проигнорирует метод def get_full_name() в классе-родителя и сразу перейдет к методу def get_full_name() написанный в классе .          

tesla_1 = ElectricCar(‘tesla’, ‘model x’, 2021)
print(tesla_1.get_full_name())

Автомобиль Tesla Model X 2021 100-Квт⋅Ч

1. Установка Python 2. Выбор текстового редактора 3. Запуск программ Python в командной строке 4. Числа и арифметические операторы Python 5.Строки и функция Print в Python 6. Списки и кортежи в Python 7. Сегментация последовательностей в Python 8. Цикл for и функция range в Python 9. Команда if и функция input в Python 10. Словари в Python 11. Множества в Python 12. Цикл while в Python 13. Функции в Python 14. Классы в Python 15. Файлы и исключения в Python 16. Функции json. Сохранение данных Python 17.Тестирование функций и классов на Python

Please enable JavaScript to view the comments powered by Disqus.

Defining a Class

A class in Python can be defined using the keyword.

As per the syntax above, a class is defined using the keyword followed by the class name and operator after the class name, which allows you to continue in the next indented line to define class members.
The followings are class members.

A class can also be defined without any members. The following example defines an empty class using the keyword.

Example: Define Python Class
Copy

Class instantiation uses function notation. To create an object of the class, just call a class like a parameterless function that returns a new object of the class, as shown below.

Example: Creating an Object of a Class
Copy

Above, returns an object of the class, which is assigned to a local variable .
The class is an empty class because it does not contain any members.

Understanding self in Python

You can see that the first parameter of a method is always . Self is not a keyword, you can actually name that first parameter whatever you like. It does make great sense to use however, as it is a convention that is recommended you use self so that as people who read your code will know what you’re talking about. So the first argument is self, which is a reference to the object, not the class, to the object. When an object is created from the class, will reference that object. It provides a way to make other variables and objects available everywhere in a class. The variable is automatically passed to each method that’s called through an object, which is why it’s listed first in every method definition. Variables attached to are available everywhere in the class.

Understanding

The __init__() method is a function that belongs to a class, just like other methods. What is important regarding is that it’s called automatically every time you instantiate a new object from a class. In other words, it is a constructor function.

Дескрипторы

Дескрипторы — объекты, которые умеют выполнять произвольный код, когда с ними происходят какие-то действия: доступ, изменение или удаление. Пример:

Дескриптор определяет методы, которые вызываются в момент, когда происходит доступ (или удаление или редактирование) инстанса дескриптора как атрибута другого класса.

Всё это работает благодаря методу : он находит нужный атрибут и проверяет, есть ли у него метод . Если есть — вызывает его, если нет — возвращает сам атрибут.

Именно через механизм дескрипторов осуществляется доступ к атрибутам класса и инстанса. , , и тоже работают благодаря дескрипторам.

Пример

Чтобы продемонстрировать использование наследования, давайте рассмотрим пример.

Многоугольник ‒ это замкнутая фигура с 3 или более сторонами. Скажем, у нас есть класс под названием Polygon, определенный следующим образом.

class Polygon:
    def __init__(self, no_of_sides):
        self.n = no_of_sides
        self.sides = 

    def inputSides(self):
        self.sides = 

    def dispSides(self):
        for i in range(self.n):
            print("Side",i+1,"is",self.sides)

Этот класс имеет атрибуты данных для хранения количества сторон n и величины каждой стороны в виде списка, называемого sides.

Метод inputSides() принимает величину каждой стороны, а dispSides() отображает эти длины сторон.

Треугольник ‒ это многоугольник с 3 сторонами. Итак, мы можем создать класс Triangle, который наследуется от Polygon. Это делает все атрибуты класса Polygon доступными для класса Triangle.

Нам не нужно определять их снова (возможность повторного использования кода). Triangle можно определить следующим образом.

class Triangle(Polygon):
    def __init__(self):
        Polygon.__init__(self,3)

    def findArea(self):
        a, b, c = self.sides
        # calculate the semi-perimeter
        s = (a + b + c) / 2
        area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
        print('The area of the triangle is %0.2f' %area)

Однако в классе Triangle есть новый метод findArea() для поиска и печати площади треугольника. Вот пример выполнения.

>>> t = Triangle()

>>> t.inputSides()
Enter side 1 : 3
Enter side 2 : 5
Enter side 3 : 4

>>> t.dispSides()
Side 1 is 3.0
Side 2 is 5.0
Side 3 is 4.0

>>> t.findArea()
The area of the triangle is 6.00

Мы видим, что, хотя мы не определили такие методы, как inputSides() или dispSides() отдельно для класса Triangle, мы смогли их использовать.

Если атрибут не найден в самом классе, поиск продолжается до базового класса. Это повторяется рекурсивно, если базовый класс сам является производным от других классов.

Объекты

Объект – это экземпляр класса. Используйте класс Shark для создания объекта jimmy.

Вы инициализировали объект jimmy как экземпляр класса.

Теперь добавьте методы класса Shark в объект jimmy:

Теперь объект jimmy, созданный на основе класса Shark, использует методы swim() и be_awesome(), которые были вызваны с помощью оператора-точки. Этот оператор позволяет сослаться на атрибут объекта.  В этом случае атрибут является методом, и он вызывается со скобками, как любая обычная функция.

Поскольку ключевое слово self является параметром методов, как определено в классе Shark, объект jimmy передается методам. Параметр self позволяет методам ссылаться на атрибуты объекта.

При вызове методов объект jimmy автоматически передается с помощью оператора-точки.

Добавьте объект в файл shark.py:

Запустите программу:

Наследование

Наследование — это способ создания нового класса на основе старого. Новый класс является производным классом (дочерним). Существующий класс является базовым классом (родительским).

Пример 3: Использование наследования в Python

# родительский класс
class Bird:
    
    def __init__(self):
        print("Bird is ready")

    def whoisThis(self):
        print("Bird")

    def swim(self):
        print("Swim faster")

# дочерний класс
class Penguin(Bird):

    def __init__(self):
        # вызов функции super()
        super().__init__()
        print("Penguin is ready")

    def whoisThis(self):
        print("Penguin")

    def run(self):
        print("Run faster")

peggy = Penguin()
peggy.whoisThis()
peggy.swim()
peggy.run()

Результат работы программы:

Bird is ready
Penguin is ready
Penguin
Swim faster
Run faster

Сначала мы создали два класса: Bird (родительский класс) и Penguin (дочерний класс). Он наследует функции родительского класса. Это прослеживается в методе  swim().

Дочерний класс изменил поведение родительского класса – метод whoisThis(). Также мы расширяем родительский класс, создав новый метод run().

Мы используем функцию super() перед методом __init__(), чтобы извлечь содержимое метода __init__() из родительского класса в дочерний.

Определение класса

Вот самая базовая структура определения класса Python.

class ClassName:  
    # list of python class variables  
    # python class constructor  
    # python class method definitions

Теперь поработаем с реальными примерами.

#definition of the class starts here  
class Person:  
    #initializing the variables  
    name = ""  
    age = 0  
      
    #defining constructor  
    def __init__(self, personName, personAge):  
        self.name = personName  
        self.age = personAge  
  
    #defining class methods  
    def showName(self):  
        print(self.name)  
  
    def showAge(self):  
        print(self.age)  
          
    #end of the class definition  
  
# Create an object of the class  
person1 = Person("John", 23)  
#Create another object of the same class  
person2 = Person("Anne", 102)  
#call member methods of the objects  
person1.showAge()  
person2.showName() 

Этот пример не требует пояснений. Как мы знаем, строки, начинающиеся с символа «#», представляют собой комментарии в Python. Они объясняют исполняемые шаги, а код дает следующий результат.

Определение класса в Python:

class Person: 

Эта строка отмечает начало определения класса для класса «Person».

Готовимся к моделированию

Теперь, когда мы знакомы с данными, пришло время подготовить их к моделированию. Как упоминалось ранее, объекты имеют буквы, представляющие различные возможные значения, но нам нужно превратить их в числа.

Для этого мы будем использоватькодирование этикеткиа такжегорячая кодировка

Давайте сначала используем кодирование метки в целевом столбце. Запустите следующий код:

И вы заметили, что теперь столбец содержит 1 и 0.


Результат метки, кодирующей столбец «класс»

Теперь ядовитый представлен 1, а съедобный — 0. Теперь мы можем думать о нашем классификаторе как «ядовитый или нет». Ядовитый гриб получает 1 (true), а съедобный гриб — 0 (false).

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

Зачем?

Потому что тогда он будет присваивать каждое значение либо 0, 1 или 2 Это проблема, потому что «2» можно рассматривать какболее важныйи из этого можно извлечь ложные корреляции.

Чтобы избежать этой проблемы, мы используемгорячее кодированиена других особенностях. Чтобы понять, что он делает, давайте рассмотрим форму крышки первой точки входа. Вы видите, что оно имеет значение «х», которое обозначает выпуклую форму колпачка. Однако в наборе данных записано всего шесть разных форм колпачков. Если мы одноразово закодируем функцию, мы должны получить:


Горячее кодирование функции «шапка-форма»

Как видите, форма шапки теперь является векторной. 1 обозначает фактическое значение формы шапки для записи в наборе данных, а остальное заполнено 0. Опять же, вы можете думать о 1 какправдаи 0 какложный.

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

Давайте продолжим и быстро закодируем остальные функции:

И теперь вы должны увидеть:


Набор горячих закодированных данных

Вы заметили, что мы поднялись с 23 столбцов до 118. Это пятикратное увеличение, но их недостаточно, чтобы вызвать проблемы с памятью компьютера.

Теперь, когда наш набор данных содержит только числовые данные, мы готовы начать моделирование и делать прогнозы!

Добавить комментарий

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