Рубрики
Без рубрики

Переопределение в Python

В этой статье мы собираемся исследовать концепцию переопределения в Python. Мы также собираемся исследовать, какие магические методы и абстрактные классы. Введение введение – это интересная концепция в объектно-ориентированном программировании. Когда метод определения базового класса изменяются в классе подкласса (полученный), это называется … переопределение в Python Подробнее »

Автор оригинала: Francisco R Porrata.

В этой статье мы собираемся исследовать концепцию переопределения в Python. Мы также собираемся исследовать, какие магические методы и абстрактные классы.

Вступление

Переопределение – это интересная концепция в объектно-ориентированном программировании. Когда метод определения базового класса изменяются в классе подкласса (полученный), это называется переопределением метода. Вы сохраняете одну и ту же подпись метода, но изменяя определение или реализацию метода, определенного одним из предков. Нет специальных синтаксисов или дополнительных ключевых слов, необходимых для проведения метода, перекрывающегося в Python. Это очень важная объектно-ориентированная концепция программирования, так как она делает наследство, используя свою полную мощность. Overriding is an interesting concept in object-oriented programming .  When the method definitions of a Base Class are changed in a Subclass (Derived) Class this is called a method override.  You are keeping the same signature of the method but changing the definition or implementation of a method defined by one of the ancestors.  There is no special syntax or additional keywords needed to do method overriding in Python.  It is a very important object-oriented programming concept since it makes inheritance exploit its full power.  In essence, you are not duplicating code, thus following the programming principle of DRY (do not repeat yourself), and you can enhance the method in the subclass. По сути, вы не дублируете код, таким образом, следуя принципу программирования сухих (не повторяйте себя), и вы можете улучшить метод в подклассе.

Чтобы понять концепцию переопределения, вы должны знать основные концепции объектно-ориентированного программирования, такие как классы и наследство. В Интернете много ресурсов о ООП. To understand the concept of overrides, you must know the basic concepts of object-oriented programming such as classes and inheritance.  There are many resources on the internet about OOP.  A really good resource is Finxter Academy’s object-oriented Python class: https://academy.finxter.com/university/object-oriented-python/Действительно хороший ресурс – это ориентированный объектно-ориентированный класс Python Academy Academy:

Нужно для переопределения

В следующем примере вы видите, как работает наследование, и проблема не переопределить метод в подклассе. У материнского класса есть метод WHOAMI Это отображает «Я родитель» Отказ In the following example, you see how inheritance works and the problem of not overriding a method in the subclass.  The Parent class has a method whoami that displays "I am a parent" .  This method is inherited by the Child class.  Calling the

Пример наследования без переопределения метода:

class Parent():
    def whoami(self):
        print("I am a parent")

class Child(Parent):
    def play(self):
        print(" I am playing")

child = Child()
child.whoami()

# Output:
# I am a parent

Основное переопределение

Следующий пример показывает, как основные переопределенные работы. В этом примере Ребенок Класс имеет определение WHOAMI Метод, который переопределяет метод от Родитель учебный класс. Призывая WHOAMI Метод от Ребенок Класс теперь отображает «Я ребенок» Отказ

Базовый переопределенный пример:

#Overriding
class Parent():
    def whoami(self):
        print("I am a parent")

class Child(Parent):
    def play(self):
        print(" I am playing")

    def whoami(self):
        print("I am a child")
        
parent = Parent()
parent.whoami()
print()
child = Child()
child.whoami()

# Output:
# I am a parent
# I am a child

Расширение метода через переопределение

Третий пример показывает, как вы можете простираться Способ в базовом классе путем переопределения метода в подклассе. The third example shows how you can extend a method in a Base Class by overriding the method in the Subclass.  To do that we use the

Сотрудник Класс имеет следующие данные для сотрудника: номер сотрудника, имя сотрудника, зарплата и, номер отдела. Эта информация передается в экземпляр объекта в __init__ метод. Showemployeree Способ класса затем отображает эту информацию, отформатированную с помощью новых строк.

Продавец класс наследует от Сотрудник учебный класс. По умолчанию он наследует Showemployeree метод как есть из Сотрудник учебный класс. Единственная проблема заключается в том, что мы хотим показать комиссию, что продавец получает в рамках печатной информации. Вот где требуется переопределение. Мы хотим повторно использовать Showemployeree Метод от Сотрудник учебный класс Но мы хотим продлить его, чтобы добавить информацию комиссии. Это достигается с помощью Super () Встроенная функция. В приведенном ниже примере вы видите, что в Продавец Класс, Super () используется дважды. The Salesman class inherits from the Employee class.  By default, it inherits the showEmployee method as-is from the Employee class.  The only problem is that we want to display the commission that the salesman receives as part of the printed information.  Here is where overriding is needed.  We want to reuse the showEmployee method from the

Третий класс называется Генеральный директор использует ту же логику, что и раньше. A third class called CEO uses the same logic as before.  The showEmployee method in this case displays the employee information plus the stock options for the

class Employee():
    def __init__(self, empno, ename, salary, deptno):
        self.Empno = empno
        self.Ename = ename
        self.Salary = salary
        self.Deptno = deptno
    
    def showEmployee(self):
        print("Employee # : {}\nEmployee Name : {}\nSalary : {}\nDepartment : {}".format(self.Empno, self.Ename, self.Salary, self.Deptno))
              
class Salesman(Employee):
    def __init__(self, empno, ename, salary, deptno, comm):
        self.Commission = comm
        super().__init__(empno, ename, salary, deptno)
              
    def showEmployee(self):
        print("Salesman Profile")       
        super().showEmployee()      
        print("Commision : ", self.Commission)

class CEO(Employee):
    def __init__(self, empno, ename, salary, deptno, stock):
        self.Stock = stock
        super().__init__(empno, ename, salary, deptno)
              
    def showEmployee(self):
        print("CEO Profile")      
        super().showEmployee()      
        print("Stock Options : ", self.Stock)

              
salesman = Salesman(200, "John Doe", 67000, "Sales", 100)
salesman.showEmployee()
print("")
ceo = CEO(40, "Jennifer Smith", 300000, "Director", 1000000)
ceo.showEmployee()              

Выход:

Salesman Profile
Employee # : 200
Employee Name : John Doe
Salary : 67000
Department : Sales
Commision :  100

CEO Profile
Employee # : 40
Employee Name : Jennifer Smith
Salary : 300000
Department : Director
Stock Options :  1000000

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

Понимание Многократное наследование имеет свои проблемы. Одним из них является использование Super () Отказ Вот ссылка на статью об этом вопросе: https://www.datacamp.com/community/tutorials/super-multiple-ineritance-diamond-problem.

В приведенном ниже примере я хотел показать способ переопределить способ из подкласса с несколькими наследованиями. In the example below, I wanted to show a way to override a method from a subclass with multiple inheritance.  The example consists of three classes: Account , Customer , and Orders . Пример состоит из трех классов:

  • Учетная запись Класс имеет свое имя и номер и метод отображения, который отображает эту информацию.
  • Клиент Класс имеет также свое имя и номер и метод отображения, который отображает эту информацию.
  • Заказы Класс отображает информацию о заказе для клиента на конкретном счете. Он наследует как из Учетная запись и класс заказов. The

Вот пример:

class Account():
    def __init__(self, name, number):
        self.Name = name
        self.Number = number
    
    def display(self):
        print("Account # : {}\nAccount Name : {}".format(self.Number, self.Name))
              
class Customer():
    def __init__(self, name, number):
        self.Name = name
        self.Number = number
              
    def display(self):
        print("Customer # : {}\nCustomer Name : {}".format(self.Number, self.Name))

class Orders(Account, Customer):
    def __init__(self, acctnumber, acctname, custnumber, custname, ordnumber, ordnamename, product, qty):
        self.OrdNumber = ordnumber
        self.Product = product
        self.Qty = qty
        self.OrdName = ordnamename
        self.acct = Account(acctname, acctnumber)
        self.cust = Customer(custname, custnumber)
              
    def display(self):
        print("Order Information")
        self.acct.display()
        self.cust.display() 
        print("Order # : {}\nOrder Name : {}\nProduct : {}\nQuantiy : {}".format(self.OrdNumber, self.OrdName, self.Product, self.Qty))

acct = Account("AB Enterprise", 12345)
acct.display()
print("")
cust = Customer("John Smith", 45678)
cust.display()
print("")
order = Orders(12345, "AB Enterprise", 45678,"John Smith", 1, "Order 1", "Widget", 5, )
order.display()

Выход:

Account # : 12345
Account Name : AB Enterprise

Customer # : 45678
Customer Name : John Smith

Order Information
Account # : 12345
Account Name : AB Enterprise
Customer # : 45678
Customer Name : John Smith
Order # : 1
Order Name : Order 1
Product : Widget
Quantiy : 5

Различные переопределенные сценарии

1 – Методы класса

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

Методы классов написаны аналогично методам регулярных экземпляров. Одно отличие – это использование Декоратор @classmethod Чтобы определить, что метод является методом класса. Также по Конвенции, а не используя себя, чтобы ссылаться на экземпляр класса, CLS использует для ссылки класса. Class methods are written similarly to regular instance methods.  One difference is the use of the

class Account():
    @classmethod
    def getClassVersion(cls):
        print("Account class version is 1.0")

Для получения дополнительной информации о методах класса проверьте это интернет сайт.

Вот пример проблемы, когда вы столкнетесь при переопределении метода класса:

class ParentClass:
    @classmethod
    def display(cls, arg):
        print("ParentClass")
        
class SubClass(ParentClass):
    @classmethod
    def display(cls, arg):
        ret = ParentClass.create(cls, arg)
        print("Subclass")
        return ret
    
SubClass.display("test")

Выход:

create() takes 2 positional arguments but 3 were given

В Подкласс звонок к Parentclass Способ создания не является несвязанным вызовом, как это происходит с нормальным методом экземпляра. Итоги этого звонка – это Типеррор Потому что метод получил слишком много аргументов.

Решение для использования Super () Для успешного использования родительской реализации.

class ParentClass:
    @classmethod
    def display(cls, arg):
        print("ParentClass")
        
        
        
class SubClass(ParentClass):
    @classmethod
    def display(cls, arg):
        ret = super(SubClass, cls).create(arg)
        print("Subclass")
        return ret
    
SubClass.display("test")

Выход:

ParentClass
Subclass

2 – Магические методы

Что такое магические методы?

Magic Methods – это набор методов, которые Python автоматически связывается с каждым определением класса. Ваши классы могут переопределить эти магические методы для реализации различных поведений и заставить их действовать так же, как встроенные классы Python. Ниже вы увидите примеры двух наиболее распространенных: __str__ и __repl__ Отказ Используя эти два метода, вы можете реализовать, как ваши объекты отображаются в виде строк, которые будут важны при отладке и представлении информации пользователю. Переопределение этих методов добавляет гибкость и мощность Python.

__str__ Способ класса используется, когда Python печатает объект. Этот магический метод называется утра Встроенная функция.

class DemoMagic():
    def display(self):
        print("Demo Magic class")
       
varDemo = DemoMagic()
varDemo.display()
str(varDemo)  

Выход:

Demo Magic class
'<__main__.DemoMagic object at 0x000002A7A7F64408>'

class DemoMagic():
def display(self):
        print("Demo Magic class")
        
def __str__(self):
        return "Override of str function"
        
varDemo = DemoMagic()
varDemo.display()
str(varDemo)     

Выход:

Demo Magic class
'Override of str function'

__repr__ Способ класса используется для отображения деталей значений объекта. Этот магический метод называется встроенным репре функция.

class Person(object):
    def __init__(self, firstname, lastname):
         self.first = firstname
         self.last = lastname

    def __repr__(self):
        return "%s %s" % (self.first, self.last)
    
Tom = Person("Tom", "Sawyer")
repr(Tom)

Выход

'Tom Sawyer'

Вот список магических методов. Вы можете узнать больше о них здесь ( https://www.tutorialsteacher.com/python/magic-methods-in-python ) И подумайте, как переопределить их, чтобы соответствовать вашим потребностям:

'__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__'

3 – Абстрактные классы

Абстрактный класс – это план, что подклассы должны следовать. An abstract class is a blueprint that subclasses must follow.  It can be viewed as a contract between the abstract class and the subclass.  The abstract class tells you what to do by providing an empty abstract method and the subclass must implement it.  By default, you must override the abstract methods defined by the abstract class.  In other terms, we are providing a common interface for different implementations of a class.  This is very useful for large projects where certain functionality must be implemented. Он можно рассматривать как договор между абстрактным классом и подклассом. An abstract class is a blueprint that subclasses must follow.  It can be viewed as a contract between the abstract class and the subclass.  The abstract class tells you what to do by providing an empty abstract method and the subclass must implement it.  By default, you must override the abstract methods defined by the abstract class.  In other terms, we are providing a common interface for different implementations of a class.  This is very useful for large projects where certain functionality must be implemented. Абстрактный класс говорит вам, что делать, предоставляя пустой абстрактный метод, а подкласс должен его реализовать. По умолчанию вы должны переопределить абстрактные методы, определенные абстрактным классом. В других условиях мы предоставляем общий интерфейс для разных реализаций класса. Это очень полезно для крупных проектов, где необходимо реализовать определенные функциональные возможности.

Вот пример абстрактного класса и перевысимых методов в подклассах.

from abc import ABC, abstractmethod 
class Animal(ABC): 
       @abstractmethod
    def whoami(self): 
        pass

class Dog(Animal): 
  
    def move(self): 
        print("I am a dog") 

class Cat(Animal): 
  
    def move(self): 
        print("I am a cat") 

Вывод

Переопределение – это базовая концепция, используемая во многих местах в объектно-ориентированном программировании. Вы должны понимать, что он сможет реализовать лучшие классы и изменять их поведение. Эта статья показывает вам несколько примеров, в которых вы можете использовать переопределение в Python. Другие понятия, упомянутые, которые стоит узнать больше о следующих достопримечательностях: магический метод и абстрактные классы.