Объектно-ориентированное программирование
- Есть разные стили (парадигмы) организации кода. До сих пор мы использовали структруное программирование. Далее мы рассмотрим объекнтно-ориентированное.
- Создайте файл student.py и наберите в нем:
Эта программа следует структруному стилю программировония. В структурном подходе мы разбиваем задачу на подзадачи, создаем для них фукции и выражаем решение через вызов функций.name = input("Name: ") house = input("House: ") print(f"{name} from {house}") -
Мы можем создать вспомогательные функции.
get_name и get_house нужны, чтобы абстраигроваться от решения подзадач в main функции.def main(): name = get_name() house = get_house() print(f"{name} from {house}") def get_name(): return input("Name: ") def get_house(): return input("House: ") if __name__ == "__main__": main() -
Мы можем далее упростить программу, используя tuple (кортеж).
tuple - последовательность значений.
В отилчие от list (список), tuple не может быть изменён.
def main(): name, house = get_student() print(f"{name} from {house}") def get_student(): name = input("Name: ") house = input("House: ") return name, house if __name__ == "__main__": main() -
Реализуем программу, используя словарь (dict).
В словаре мы можем указывать на элемент ключом.class Student: def __init__(self, name, house): self.name = name self.house = house def main(): student = get_student() print(f"{student.name} from {student.house}") def get_student(): name = input("Name: ") house = input("House: ") return Student(name, house) if __name__ == "__main__": main() - Класс - способ создать свой тип данных и дать ему имя. Этот инструмент используется в объектно-ориентированном программировании.
-
Изменим наш код. Создадим класс Student.
Для создания класса, используем ключевое слово class. Конструкор класса Student() создает объект класса. Чтобы получить значение свойства объекта класса, используем точку после имени объекта, например, student.name.class Student: # Создаем класс ... def main(): student = get_student() print(f"{student.name} from {student.house}") def get_student(): student = Student() # создаем объект student.name = input("Name: ") # задаем свойство student.house = input("House: ") return student if __name__ == "__main__": main() - Класс - это шаблон для создания экземпляров (объектов).
-
Мы можем создавать функции в классе их принято назваыть методы.
Специальная функция класса ининциализирующая его свойства называется
конструктор.
Посмотрим как можно задать конструктор класса.
self используется для ссылки на объект.class Student: def __init__(self, name, house): self.name = name self.house = house def main(): student = get_student() print(f"{student.name} from {student.house}") def get_student(): name = input("Name: ") house = input("House: ") return Student(name, house) if __name__ == "__main__": main() - Смотри документацию на классы.
Классы
raise
-
Используем функцию raise, чтобы создать исключение, если пользователь
ошибся.
Код создаёт объект класса ValueError c текстом.class Student: def __init__(self, name, house): if not name: raise ValueError("Missing name") if house not in ["Gryffindor", "Hufflepuff", "Ravenclaw", "Slytherin"]: raise ValueError("Invalid house") self.name = name self.house = house def main(): student = get_student() print(f"{student.name} from {student.house}") def get_student(): name = input("Name: ") house = input("House: ") return Student(name, house) if __name__ == "__main__": main() -
Если мы зададим для нашего класса функцию __str__, то
функция print сможет печатать его объекты.
class Student: def __init__(self, name, house): if not name: raise ValueError("Missing name") if house not in ["Gryffindor", "Hufflepuff", "Ravenclaw", "Slytherin"]: raise ValueError("Invalid house") self.name = name self.house = house def __str__(self): return f"{self.name} from {self.house}" def main(): student = get_student() print(student) def get_student(): name = input("Name: ") house = input("House: ") return Student(name, house) if __name__ == "__main__": main()
Декораторы
- Декораторы функций начинаются с @
class Student: def __init__(self, name, house): if not name: raise ValueError("Missing name") if house not in ["Gryffindor", "Hufflepuff", "Ravenclaw", "Slytherin"]: raise ValueError("Invalid house") self.name = name self.house = house def __str__(self): return f"{self.name} from {self.house}" @property def house(self): return self._house @house.setter def house(self, house): if house not in ["Gryffindor", "Hufflepuff", "Ravenclaw", "Slytherin"]: raise ValueError("Invalid house") self._house = house def main(): student = get_student() student.house="Slytherin" print(student) def get_student(): name = input("Name: ") house = input("House: ") return Student(name, house) if __name__ == "__main__": main()
Методы класса
- Можно задать функцию класса а не объекта.
- Создадим файл hat.py не использующий метода класса.
import random class Hat: def __init__(self): self.houses = ["Gryffindor", "Hufflepuff", "Ravenclaw", "Slytherin"] def sort(self, name): print(name, "is in", random.choice(self.houses)) hat = Hat() hat.sort("Harry") - Мы можем использовать функцию sort не создавая объекта класса. Изменим
наш код:
import random class Hat: houses = ["Gryffindor", "Hufflepuff", "Ravenclaw", "Slytherin"] @classmethod def sort(cls, name): print(name, "is in", random.choice(cls.houses)) Hat.sort("Harry") -
Изменим файл student.py, добавив @classmethod
class Student: def __init__(self, name, house): self.name = name self.house = house def __str__(self): return f"{self.name} from {self.house}" @classmethod def get(cls): name = input("Name: ") house = input("House: ") return cls(name, house) def main(): student = Student.get() print(student) if __name__ == "__main__": main()
Наследование
- Можно создать класс, которые наследует свойства и методы другого.
-
Создайте файл wizar.py. С кодом:
class Wizard: def __init__(self, name): if not name: raise ValueError("Missing name") self.name = name class Student(Wizard): def __init__(self, name, house): super().__init__(name) self.house = house class Professor(Wizard): def __init__(self, name , subject): super().__init__(name) self.subject = subject wizard = Wizard("Albus") student = Student("Harry", "Gryffindor") professor = Professor("Severus", "Defense Against the Dark Arits") print(student.name)
Перегрузка операторов
- Некоторые операторы, такие как +, -, могут быть перегружены.
- Создайте файл vault.py. Наберите в нем:
class Vault: def __init__(self, galleons=0, sickles=0, knuts=0): self.galleons = galleons self.sickles = sickles self.knuts = knuts def __str__(self): return f"{self.galleons} Galleons, {self.sickles} Sickles, {self.knuts} Rnuts" def __add__(self, other): galleons = self.galleons + other.galleons sickles = self.sickles + other.sickles knuts = self.knuts + other.knuts return Vault(galleons, sickles, knuts) potter = Vault(100, 50, 25) print(potter) weasley = Vault(25, 50, 100) print(weasley) total= potter + weasley print(total)