Python. Создание класса-списка, реализованный на основе массива
День добрый. Я в ооп на Python довольно не продолжительное время нахожусь(если можно так выразиться), и в связи с учебой этому ремеслу появился вопрос. Возможно ли создать класс-список, реализованный на основе массива? Этот класс-список принимает экземпляры других классов, а методы, которые находятся в этом классе — это те же методы, что и у структуры данных на Python(списка). Прошу помощи
class ClassList(): def __init__(self): self.list = [] def __str__(self): return self.list def append(self, ob): self.list.append(ob) a = input("Введите данные: ").split(', ') car = Car(a[0], a[1], a[2], a[3], a[4], a[5], a[6]) array = ClassList() array.append(car) array.append(car_copy) print(array.__str__())
А это то, что получается на выходе, хотя метод str класса Car переопределен
Отслеживать
48.6k 17 17 золотых знаков 56 56 серебряных знаков 100 100 бронзовых знаков
задан 18 апр 2020 в 5:25
Олег Барнев Олег Барнев
1 1 1 серебряный знак 2 2 бронзовых знака
А что список это не массив?
18 апр 2020 в 11:23
Вы покажите как вы пытаетесь реализовать задуманное, может всё гораздо проще чем вы думаете
18 апр 2020 в 11:24
Добавьте ваш класс Car
18 апр 2020 в 17:06
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Возможно ли создать класс-список, реализованный на основе массива?
Этот класс-список принимает экземпляры других классов,
тут понятно, что будут проблемы. Если вы решили действительно (например — в учебных целях) реализовывать список на массиве — то массив по определению «последовательность однотипных элементов». Соответственно, экземпляр произвольного (или тем более — разных) классов вы в такой список непосредственно не засунете.
Однако, если вы допускаете возможность работать с массивом указателей, каждый из которых будет указывать на свой объект-экземпляр «другого класса» — то так вполне можно. Более того, в Python список реализован именно по подобной схеме, а не как классический список.
а методы, которые находятся в этом классе — это те же методы, что и у структуры данных на Python(списка).
Ну, какие методы реализуете самостоятельно — такие будут. Хоть те же, хоть подобные, хоть какие-то специфические (если надо).
Класс list() в Python, преобразовывает в список
Создает пустой список или преобразовывает последовательность в список
Синтаксис:
list(iterable)
Параметры:
- iterable — последовательность или объект, поддерживающий итерирование (включая генераторы).
Возвращаемое значение:
- list , изменяемая последовательность с упорядоченными элементами.
Описание:
Класс list() создает или преобразует переданный объект, поддерживающий итерирование, в список (изменяемую последовательность с упорядоченными элементами). Элементы в списках упорядочены по очередности их добавления.
Если аргумент iterable не указан, будет создан пустой список.
Примеры преобразования последовательности в список.
Создание списка list :
x = list() print(x) # [] x = list([1, 'foo', 2]) print(x) # [1, 'foo', 2]
Преобразовать кортеж tuple в список:
x = ('apple', 'banana', 'cherry') list(x) # ['apple', 'banana', 'cherry']
Преобразовать множество set в список:
x = 'apple', 'banana', 'cherry'> list(x) # ['apple', 'banana', 'cherry']
При преобразовании словаря dict в список попадают только ключи.
x = dict(apple='green', banana='yellow', cherry='red') list(x) # ['apple', 'banana', 'cherry']
Преобразовать диапазон range в список:
x = range(3) list(x) # [0, 1, 2]
- ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
- Функция abs(), абсолютное значение числа
- Функция all(), все элементы True
- Функция any(), хотя бы один элемент True
- Функция ascii(), преобразует строку в ASCII
- Функция bin(), число в двоичную строку
- Класс bool(), логическое значение объекта
- Функция breakpoint(), отладчик кода
- Класс bytearray(), преобразует в массив байтов
- Класс bytes(), преобразует в строку байтов
- Функция callable(), проверяет можно ли вызвать объект
- Функция chr(), число в символ Юникода
- Класс classmethod, делает функцию методом класса
- Функция compile() компилирует блок кода Python
- Класс complex(), преобразует в комплексное число
- Функция delattr(), удаляет атрибут объекта
- Класс dict() создает словарь
- Функция dir(), все атрибуты объекта
- Функция divmod(), делит числа с остатком
- Функция enumerate(), счетчик элементов последовательности
- Функция eval(), выполняет строку-выражение с кодом
- Функция exec(), выполняет блок кода
- Функция filter(), фильтрует список по условию
- Класс float(), преобразует в вещественное число
- Функция format(), форматирует значение переменной
- Класс frozenset(), преобразует в неизменяемое множество
- Функция getattr(), значение атрибута по имени
- Функция globals(), переменные глобальной области
- Функция hasattr(), наличие атрибута объекта
- Функция hash(), хэш-значение объекта
- Функция help(), справка по любому объекту
- Функция hex(), число в шестнадцатеричную строку
- Функция id(), идентификатор объекта
- Функция input(), ввод данных с клавиатуры
- Класс int(), преобразует в тип int
- Функция isinstance(), принадлежность экземпляра к классу
- Функция issubclass(), проверяет наследование класса
- Функция iter(), создает итератор
- Функция len(), количество элементов объекта
- Класс list(), преобразовывает в список
- Функция locals(), переменные локальной области
- Функция map(), обработка последовательности без цикла
- Функция max(), максимальное значение элемента
- Класс memoryview(), ссылка на буфер обмена
- Функция min(), минимальное значение элемента
- Функция next(), следующий элемент итератора
- Класс object(), возвращает безликий объект
- Функция oct(), число в восьмеричную строку
- Функция open(), открывает файл на чтение/запись
- Функция ord(), число символа Unicode
- Функция pow(), возводит число в степень
- Функция print(), печатает объект
- Класс property(), метод класса как свойство
- Класс range(), генерирует арифметические последовательности
- Функция repr(), описание объекта
- Функция reversed(), разворачивает последовательность
- Функция round(), округляет число
- Класс set(), создает или преобразовывает в множество
- Функция setattr(), создает атрибут объекта
- Класс slice(), шаблон среза
- Функция sorted(), выполняет сортировку
- Декоратор staticmethod(), метод класса в статический метод
- Класс str(), преобразует объект в строку
- Функция sum(), сумма последовательности
- Функция super(), доступ к унаследованным методам
- Класс tuple(), создает или преобразует в кортеж
- Класс type(), возвращает тип объекта
- Функция vars(), словарь переменных объекта
- Функция zip(), объединить элементы в список кортежей
- Функция __import__(), находит и импортирует модуль
- Функция aiter(), создает асинхронный итератор
- Функция anext(), следующий элемент асинхронного итератора
Список list в Python
Списки представляют собой изменяемые последовательности, обычно используемые для хранения коллекций однородных элементов, где степень сходства зависит от приложения.
Списки поддерживают следующие операции:
- общие операции с последовательностями;
- операции с изменяемыми последовательностями.
В Python списки представлены встроенным классом list() , его можно использовать для преобразования итерируемых объектов в тип list .
Списки могут быть созданы несколькими способами:
- Используя пару квадратных скобок для обозначения пустого списка: [] .
- Используя квадратные скобки, разделяя элементы запятыми: [a, b, c] .
- Используя генератор списка: [x for x in iterable] .
- Используя конструктор типа list :
- list() — создаст пустой список,
- list(iterable) — преобразует в список объект, который поддерживает итерацию.
Конструктор класса list(iterable) создает список, элементы которого совпадают и находятся в том же порядке, что и элементы итератора iterable . Аргумент iterable может быть либо последовательностью, контейнером поддерживающим итерацию, либо объектом итератора. Если аргумент не задан, конструктор создает новый пустой список [] .
- Если код программы многократно использует операцию вхождения в список list , то для этой цели лучше использовать множество set . Множества set / frozenset специально заточены для этой цели.
- Когда код программы часто добавляет элементы списка с одной стороны и удаляет с другой стороны (методы с изменяемыми последовательностями это делать позволяют). В этом случае следует использовать класс deque который представляет собой двустороннюю очередь, которая предназначена для быстрого добавления и удаления элементов с обоих концов последовательности.
Список list способен хранить в себе разные типы данных.
Примеры использования создания списка и преобразования объектов к типу list :
>>> list() # Создание списка # [] >>> [] # [] >>> [1, 'a', 10, 'b', '105'] # [1, 'a', 10, 'b', '105'] # Преобразование строки str в список тип list >>> list('abc') # ['a',' b',' c'] # Преобразование кортежа tuple в список тип list >>> list((1, 2, 3)) # [1, 2, 3] # Преобразование множества set в список тип list >>> list(1, 2, 3>) # [1, 2, 3] # Преобразование генератора в список тип list >>> list(range(5)) # [0, 1, 2, 3, 4] # Преобразуем список строк в список чисел x = ['55', '11', '25', '15', '9'] int_list = [int(i) for i in x] print(int_list) # [11, 15, 25, 55, 9]
Если объект iterable уже является списком, создается и возвращается копия, аналогичная iterable[:] . Многие другие операции также создают списки, в том числе встроенная функция sorted() .
Списки имеют дополнительный метод:
list.sort(*, key=None, reverse=False) :
Метод list.sort() принимает два аргумента, которые могут передаваться только по ключевому слову:
- key определяет функцию с одним аргументом, которая используется для извлечения ключа сравнения из каждого элемента списка, например, key=str.lower . Ключ, соответствующий каждому элементу в списке, вычисляется один раз и затем используется для всего процесса сортировки. Значение по умолчанию None означает, что элементы списка сортируются напрямую без вычисления отдельного значения ключа.
- reverse это логическое значение. Если установлено значение True , то элементы списка сортируются так, как если бы каждое сравнение было обратным.
Метод изменяет последовательность на месте для экономии памяти при сортировке большой последовательности. Чтобы напомнить пользователям, что он работает с таким эффектом, он не возвращает отсортированную последовательность. Для того, что бы получить копию отсортированного списка используйте встроенную функцию сортировки sorted() .
Метод list.sort() гарантированно будет стабильным. Сортировка является стабильной, если она гарантирует отсутствие изменения относительного порядка элементов, которые будут равными в сортируемом списке. Это полезно для сортировки за несколько проходов, например сортировка по отделу, а затем по уровню зарплаты.
Примеры использования сортировки списка методом sort() :
>>> x = [5, 2, 3, 1, 4] >>> x.sort() >>> x # [1, 2, 3, 4, 5] # Обратная сортировка - reverse=True >>> x = [5, 2, 3, 1, 4] >>> x.sort(reverse=True) >>> x # [5, 4, 3, 2, 1]
Сортировка по длине строки, в качестве функции сортировки выступает встроенная len() :
>>> x = ['a', 'dddd', 'сс', 'bbb'] >>> x.sort(key=len) >>> x # ['a', 'сс', 'bbb', 'dddd']
В следующем примере, в списке x представлена последовательность чисел в качестве строк. При простой сортировке будет использоваться лексикографическое сравнение.
>>> x = ['55', '11', '25', '15', '9'] >>> x.sort() >>> x # ['11', '15', '25', '55', '9']
Применим в качестве ключевой функции для сравнения класс int() , для преобразования строк в целые числа, что бы упорядочить последовательность строк как будто это список чисел.
>>> x = ['55', '11', '25', '15', '9'] >>> x.sort(key=int) >>> x # ['9', '11', '15', '25', '55']
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Утиная типизация ‘Duck Typing’
- Что такое вызываемый объект callable?
- Как проверить тип переменной/объекта
- Логический тип данных bool
- Целые числа int
- Ограничение длины преобразования целочисленной строки
- Вещественные числа float
- Комплексные числа complex
- Типы последовательностей
- Список list
- Кортеж tuple
- Диапазон range
- Текстовые строки str
- Словарь dict
- Множество set и frozenset
- Итератор Iterator, протокол итератора
- Генератор generator и выражение yield
- Контекстный менеджер with
- Байтовые строки bytes
- Байтовый массив bytearray
- Тип memoryview, буфер обмена
- Файловый объект file object
- Универсальный псевдоним GenericAlias
- Объект объединения Union
Примеры работы с классами в Python
Python — объектно-ориентированный язык с начала его существования. Поэтому, создание и использование классов и объектов в Python просто и легко. Эта статья поможет разобраться на примерах в области поддержки объектно-ориентированного программирования Python. Если у вас нет опыта работы с объектно-ориентированным программированием (OOП), ознакомьтесь с вводным курсом или учебным пособием, чтобы понять основные понятия.
Создание классов
Оператор class создает новое определение класса. Имя класса сразу следует за ключевым словом class , после которого ставиться двоеточие:
class ClassName: """Необязательная строка документации класса""" class_suite
- У класса есть строка документации, к которой можно получить доступ через ClassName.__doc__ .
- class_suite состоит из частей класса, атрибутов данных и функции.
Пример создания класса на Python:
class Employee: """Базовый класс для всех сотрудников""" emp_count = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.emp_count += 1 def display_count(self): print('Всего сотрудников: %d' % Employee.empCount) def display_employee(self): print('Имя: <>. Зарплата: <>'.format(self.name, self.salary))
- Переменная emp_count — переменная класса, значение которой разделяется между экземплярами этого класса. Получить доступ к этой переменной можно через Employee.emp_count из класса или за его пределами.
- Первый метод __init__() — специальный метод, который называют конструктором класса или методом инициализации. Его вызывает Python при создании нового экземпляра этого класса.
- Объявляйте другие методы класса, как обычные функции, за исключением того, что первый аргумент для каждого метода self . Python добавляет аргумент self в список для вас; и тогда вам не нужно включать его при вызове этих методов.
Создание экземпляров класса
Чтобы создать экземпляры классов, нужно вызвать класс с использованием его имени и передать аргументы, которые принимает метод __init__ .
# Это создаст первый объект класса Employee emp1 = Employee("Андрей", 2000) # Это создаст второй объект класса Employee emp2 = Employee("Мария", 5000)Доступ к атрибутам
Получите доступ к атрибутам класса, используя оператор . после объекта класса. Доступ к классу можно получить используя имя переменой класса:
emp1.display_employee() emp2.display_employee() print("Всего сотрудников: %d" % Employee.emp_count)Теперь, систематизируем все.
class Employee: """Базовый класс для всех сотрудников""" emp_count = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.emp_count += 1 def display_count(self): print('Всего сотрудников: %d' % Employee.emp_count) def display_employee(self): print('Имя: <>. Зарплата: <>'.format(self.name, self.salary)) # Это создаст первый объект класса Employee emp1 = Employee("Андрей", 2000) # Это создаст второй объект класса Employee emp2 = Employee("Мария", 5000) emp1.display_employee() emp2.display_employee() print("Всего сотрудников: %d" % Employee.emp_count)При выполнении этого кода, мы получаем следующий результат:
Имя: Андрей. Зарплата: 2000 Имя: Мария. Зарплата: 5000 Всего сотрудников: 2Вы можете добавлять, удалять или изменять атрибуты классов и объектов в любой момент.
emp1.age = 7 # Добавит атрибут 'age' emp1.age = 8 # Изменит атрибут 'age' del emp1.age # Удалит атрибут 'age'Вместо использования привычных операторов для доступа к атрибутам вы можете использовать эти функции:
- getattr(obj, name [, default]) — для доступа к атрибуту объекта.
- hasattr(obj, name) — проверить, есть ли в obj атрибут name .
- setattr(obj, name, value) — задать атрибут. Если атрибут не существует, он будет создан.
- delattr(obj, name) — удалить атрибут.
hasattr(emp1, 'age') # возвращает true если атрибут 'age' существует getattr(emp1, 'age') # возвращает значение атрибута 'age' setattr(emp1, 'age', 8) #устанавливает атрибут 'age' на 8 delattr(empl, 'age') # удаляет атрибут 'age'Встроенные атрибуты класса
Каждый класс Python хранит встроенные атрибуты, и предоставляет к ним доступ через оператор . , как и любой другой атрибут:
- __dict__ — словарь, содержащий пространство имен класса.
- __doc__ — строка документации класса. None если, документация отсутствует.
- __name__ — имя класса.
- __module__ — имя модуля, в котором определяется класс. Этот атрибут __main__ в интерактивном режиме.
- __bases__ — могут быть пустые tuple, содержащие базовые классы, в порядке их появления в списке базового класса.
Для вышеуказанного класса давайте попробуем получить доступ ко всем этим атрибутам:
class Employee: """Базовый класс для всех сотрудников""" emp_count = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def display_count(self): print('Всего сотрудников: %d' % Employee.empCount) def display_employee(self): print('Имя: <>. Зарплата: <>'.format(self.name, self.salary)) print("Employee.__doc__:", Employee.__doc__) print("Employee.__name__:", Employee.__name__) print("Employee.__module__:", Employee.__module__) print("Employee.__bases__:", Employee.__bases__) print("Employee.__dict__:", Employee.__dict__)Когда этот код выполняется, он возвращает такой результат:
Employee.__doc__: Базовый класс для всех сотрудников Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: (,) Employee.__dict__: , 'display_count': , 'display_employee': , '__dict__': , '__weakref__': >Удаление объектов (сбор мусора)
Python автоматически удаляет ненужные объекты (встроенные типы или экземпляры классов), чтобы освободить пространство памяти. С помощью процесса ‘Garbage Collection’ Python периодически восстанавливает блоки памяти, которые больше не используются.
Сборщик мусора Python запускается во время выполнения программы и тогда, когда количество ссылок на объект достигает нуля. С изменением количества обращений к нему, меняется количество ссылок.
Когда объект присваивают новой переменной или добавляют в контейнер (список, кортеж, словарь), количество ссылок объекта увеличивается. Количество ссылок на объект уменьшается, когда он удаляется с помощью del , или его ссылка выходит за пределы видимости. Когда количество ссылок достигает нуля, Python автоматически собирает его.
a = 40 # создали объект b = a # увеличивает количество ссылок c = [b] # увеличивает количество ссылок del a # уменьшает количество ссылок b = 100 # уменьшает количество ссылок c[0] = -1 # уменьшает количество ссылок
Обычно вы не заметите, когда сборщик мусора уничтожает экземпляр и очищает свое пространство. Но классом можно реализовать специальный метод __del__() , называемый деструктором. Он вызывается, перед уничтожением экземпляра. Этот метод может использоваться для очистки любых ресурсов памяти.
Пример работы __del__()
Деструктор __del__() выводит имя класса того экземпляра, который должен быть уничтожен:class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print('<> уничтожен'.format(class_name)) pt1 = Point() pt2 = pt1 pt3 = pt1 print(id(pt1), id(pt2), id(pt3)) # выведите id объектов del pt1 del pt2 del pt3Когда вышеуказанный код выполняется и выводит следующее:
17692784 17692784 17692784 Point уничтоженВ идеале вы должны создавать свои классы в отдельном модуле. Затем импортировать их в основной модуль программы с помощью import SomeClass .
Наследование класса в python
Наследование — это процесс, когда один класс наследует атрибуты и методы другого. Класс, чьи свойства и методы наследуются, называют Родителем или Суперклассом. А класс, свойства которого наследуются — класс-потомок или Подкласс.
Вместо того, чтобы начинать с нуля, вы можете создать класс, на основе уже существующего. Укажите родительский класс в круглых скобках после имени нового класса.
Класс наследник наследует атрибуты своего родительского класса. Вы можете использовать эти атрибуты так, как будто они определены в классе наследнике. Он может переопределять элементы данных и методы родителя.
Синтаксис наследования класса
Классы наследники объявляются так, как и родительские классы. Только, список наследуемых классов, указан после имени класса.
class SubClassName(ParentClass1[, ParentClass2, . ]): """Необязательная строка документации класса""" class_suiteПример наследования класса в Python
class Parent: # объявляем родительский класс parent_attr = 100 def __init__(self): print('Вызов родительского конструктора') def parent_method(self): print('Вызов родительского метода') def set_attr(self, attr): Parent.parent_attr = attr def get_attr(self): print('Атрибут родителя: <>'.format(Parent.parent_attr)) class Child(Parent): # объявляем класс наследник def __init__(self): print('Вызов конструктора класса наследника') def child_method(self): print('Вызов метода класса наследника') c = Child() # экземпляр класса Child c.child_method() # вызов метода child_method c.parent_method() # вызов родительского метода parent_method c.set_attr(200) # еще раз вызов родительского метода c.get_attr() # снова вызов родительского методаКогда этот код выполняется, он выводит следующий результат:
Вызов конструктора класса наследника Вызов метода класса наследника Вызов родительского метода Атрибут родителя: 200Аналогичным образом вы можете управлять классом с помощью нескольких родительских классов:
class A: # объявите класс A . class B: # объявите класс B . class C(A, B): # C наследуется от A и B .Вы можете использовать функции issubclass() или isinstance() для проверки отношений двух классов и экземпляров.
- Логическая функция issubclass(sub, sup) возвращает значение True , если данный подкласс sub действительно является подклассом sup .
- Логическая функция isinstance(obj, Class) возвращает True , если obj является экземпляром класса Class или является экземпляром подкласса класса.
Переопределение методов
Вы всегда можете переопределить методы родительского класса. В вашем подклассе могут понадобиться специальные функции. Это одна из причин переопределения родительских методов.
Пример переопределения методов:
class Parent: # объявите родительский класс def my_method(self): print('Вызов родительского метода') class Child(Parent): # объявите класс наследник def my_method(self): print('Вызов метода наследника') c = Child() # экземпляр класса Child c.my_method() # метод переопределен классом наследникомКогда этот код выполняется, он производит следующий результат:
Вызов метода наследникаПопулярные базовые методы
В данной таблице перечислены некоторые общие функции. Вы можете переопределить их в своих собственных классах.
| № | Метод, описание и пример вызова |
|---|---|
| 1 | __init__(self [, args. ]) — конструктор (с любыми необязательными аргументами) obj = className(args) |
| 2 | __del__(self) — деструктор, удаляет объект del obj |
| 3 | __repr__(self) — программное представление объекта repr(obj) |
| 4 | __str__(self) — строковое представление объекта str(obj) |
Пример использования __add__
Предположим, вы создали класс Vector для представления двумерных векторов. Что происходит, когда вы используете дополнительный оператор для их добавления? Скорее всего, Python будет против.
Однако вы можете определить метод __add__ в своем классе для добавления векторов и оператор + будет вести себя так как нужно.
class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (<>, <>)'.format(self.a, self.b) def __add__(self, other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2, 10) v2 = Vector(5, -2) print(v1 + v2)При выполнении этого кода, мы получим:
Vector(7, 8)Приватные методы и атрибуты
Атрибуты класса могут быть не видимыми вне определения класса. Вам нужно указать атрибуты с __ вначале, и эти атрибуты не будут вызваны вне класса.
Пример приватного атрибута:
class JustCounter: __secret_count = 0 def count(self): self.__secret_count += 1 print(self.__secret_count) counter = JustCounter() counter.count() counter.count() print(counter.__secret_count)При выполнении данного кода, имеем следующий результат:
1 2 Traceback (most recent call last): File "test.py", line 12, in print(counter.__secret_count) AttributeError: 'JustCounter' object has no attribute '__secret_count'Вы можете получить доступ к таким атрибутам, так object._className__attrName . Если вы замените свою последнюю строку следующим образом, то она будет работать.