Начало работы с основами Python — 5 основ объектно-ориентированного программирования

Python

Первые четыре статьи для начала работы с основами Python:

Пятая часть в основном знакомит с объектно-ориентированными основами Python, то есть введением в классы, включая методы и атрибуты классов, методы построения, переопределение методов, наследование и т. д., и, наконец, дает два простых упражнения.


5. Объектно-ориентированный

5.1 Введение

Кратко познакомимся с некоторыми понятиями существительных.

  • своего рода: используется для описанияКоллекция объектов с одинаковыми свойствами и методами. Он определяет свойства и методы, общие для каждого объекта в коллекции. Объекты являются экземплярами классов.
  • метод класса: Функции, определенные в классе.
  • переменная класса: переменная класса находится во всем созданном объекте.публичный. переменная классаОпределяется в классе и вне тела функции. переменная классаОбычно не используется в качестве переменной экземпляра.
  • элемент данных: переменные класса или переменные экземпляра используются для обработки данных, связанных с классом и его объектами экземпляра.
  • переопределение метода: Если метод, унаследованный от родительского класса, не может удовлетворить потребности подкласса, его можно переписать.Этот процесс называетсяпереопределение метода, также известен какпереопределение метода.
  • локальная переменная: переменные, определенные в методе, применяются только к классу текущего экземпляра.
  • переменная экземпляра: в объявлении класса свойства представлены переменными. Такие переменные называются переменными экземпляра и объявляются внутри объявления класса, но вне других методов-членов класса.
  • наследовать: т.е.Производный класс наследует поля и методы базового класса.. Наследование также позволяет рассматривать объект производного класса как объект базового класса. Например, существует проект, в котором объект типа Dog является производным от класса Animal, который имитирует отношение «является» (например, Dog is an Animal).
  • создавать экземпляр: Создает экземпляр класса, конкретный объект класса.
  • объект: экземпляр структуры данных, определяемой классом.Объекты включают два члена данных (переменные класса и переменные экземпляра) и методы..

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

Объекты могут содержать любое количество и тип данных.

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

Ниже приведено простое определение класса:

# 定义一个动物类别
class Animal(object):
    # 类变量
    eat = True
    
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender

     # 类方法
    def run(self):
        return 'Animal run!'
# 实例化类
anm = Animal('animal', 'male')

# 访问类的属性和方法
print("Animal 类的属性 eat 为:", anm.eat)
print("Animal 类的方法 run 输出为:", anm.run())

Выходной результат:

Animal 类的属性 eat 为: True
Animal 类的方法 run 输出为: Animal run!

Выше приведено простое определение класса, обычно класс должен иметь ключевые слова.class, за которым следует имя класса, то, если этоpython2.7необходимо добавить скобки иobject, но вpython3В версии, по сути, это может быть прямо так:

class Animal:
Представление конструкторов и специальных параметров самостоятельно

потом__init__даМетод строительства, то есть в процессесоздание экземпляра классаЭтот метод вызывается, когдаanm = Animal('animal', 'male').

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

class Test:
    def prt(self):
        print(self)
        print(self.__class__)
 
t = Test()
t.prt()

Выходной результат:

<__main__.Test object at 0x000002A262E2BA20>
<class '__main__.Test'>

можно увидетьprint(self)В результате выводится адрес текущего объекта, аself.__class__представляет класс.

только сказалselfЭто просто пользовательское имя, и вы можете изменить его на другое имя следующим образом:

# 不用 self 名称
class Test2:
    def prt(sss):
        print(sss)
        print(sss.__class__)

t2 = Test2()
t2.prt()

Вывод тот же, изменился только адрес экземпляра класса.

<__main__.Test2 object at 0x000001FB7644BBA8>
<class '__main__.Test2'>
метод класса

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

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))
 
# 实例化类
p = people('runoob',10,30)
p.speak()

выходной результат

runoob 说: 我 10 岁。

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

Синтаксис наследования определяется следующим образом:

class DerivedClassName(BaseClassName1,BaseClassName2,...):
    <statement-1>
    .
    .
    .
    <statement-N>

требует внимания:

  • в скобкахпорядок базовых классов, когда базовый класс содержит такое же имя метода, подкласс не указывается (т.е. что-то вродеBaseClass1.method1()), python будет искать слева направо, содержит ли унаследованный базовый класс этот метод;
  • Базовые и подклассы должныопределено в области;

Пример кода приведен ниже, определение базового класса все еще находится в предыдущем разделе.peopleкласс, на этот раз определяющий подклассstudent

# 单继承示例
class student(people):
    grade = ''

    def __init__(self, n, a, w, g):
        # 调用父类的构造方法
        people.__init__(self, n, a, w)
        self.grade = g

    # 覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))


s = student('ken', 10, 60, 3)
s.speak()

выходной результат

ken 说: 我 10 岁了,我在读 3 年级

Это пример одиночного наследования, то есть наследования базового класса, и конструктор подкласса должен сначала вызвать конструктор базового класса (родительского класса):

# 调用父类的构造方法
people.__init__(self, n, a, w)

Другой способ вызвать конструктор базового класса, используяsuper()функция:

super.__init__(self, n, a, w)
переопределение метода

В приведенном выше примере также переопределяется метод базового класса.speak().

Переопределение метода - это когда метод базового класса не может удовлетворить потребности подкласса, подкласс переопределяет метод суперкласса.

множественное наследование

Python также поддерживает множественное наследование, ниже приведен пример, продолжайте использовать только что определенный классstudent, а затем переопределить базовый классspeaker

#另一个类,多重继承之前的准备
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
 
#多重继承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)
 
test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同,默认调用的是在括号中排前地父类的方法

Выходной результат:

我叫 Tim,我是一个演说家,我演讲的主题是 Python

И если вы хотите указать метод любого родительского класса, вы можете добавить следующий код:

# 显示调用 student 父类的 speak 方法
def speak(self):
    super(student, self).speak()

Как описано выше,super()Функция — это метод вызова родительского класса, который может быть напрямуюsuper().method(), но если это множественное наследование и указан родительский класс, как показано выше, добавьте имя родительского класса иselfдля представления экземпляра класса.

Кроме того,python2.7перечислитьsuper()метод, вам также необходимо передать имя родительского класса иselfдва параметра.

5.4 Атрибуты и методы класса

свойства и методыразрешение на доступ, а именно видимость, бывает трех видов,публичный, защищенный и частный, частные методы и частные свойства определяются следующим образом:

  • частная собственность класса: Начните с двух знаков подчеркивания, объявите, что свойство является закрытым и не может быть использовано или доступно напрямую вне класса, но при использовании в методах внутри класса:self.__private_attrs

  • закрытый метод класса: Начните с двух символов подчеркивания, объявите, что метод является закрытым методом и может быть вызван только внутри класса, а не вне класса.self.__private_methods.

И если это защищенное свойство или метод, то оно начинается, например, с подчеркивания_protected_attr.

Вот простой пример:

class JustCounter:
    __secretCount = 0  # 私有变量
    publicCount = 0  # 公开变量

    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print(self.__secretCount)
        self.__count()

    def __count(self):
        print('私有方法')


counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCount)
print(counter.__secretCount)  # 报错,实例不能访问私有变量
print(counter.__count())

выходной результат

1
私有方法
2
私有方法
2

Вызов частной собственности вызывает ошибку:

AttributeError: 'JustCounter' object has no attribute '__secretCount'

Вызов приватного метода выдает ошибку:

AttributeError: 'JustCounter' object has no attribute '__count'

Свойством класса может быть не только переменная, но и экземпляр класса как свойство, пример такой:

class TimeCounter:
    def __init__(self):
        print('timer')


class JustCounter:
    __secretCount = 0  # 私有变量
    publicCount = 0  # 公开变量

    def __init__(self):
        self.timer = TimeCounter()

    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print(self.__secretCount)
        self.__count()

    def __count(self):
        print('私有方法')


counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCount)

также продолжайте использоватьJustCounterкласс, просто новое определениеTimeCounter, И вJustCounterВызов конструктора для создания экземпляраTimeCounterкласс, результат вывода:

timer
1
私有方法
2
私有方法
2

5.5 Упражнение

наконец изPython-100-Days--Day08 Основы объектно-ориентированного подходадва практических вопроса:

Определение простых цифровых часов

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

from time import sleep


class Clock(object):
    """数字时钟"""

    def __init__(self, hour=0, minute=0, second=0):
        '''
        初始化三个基本属性,时,分,秒
        :param hour:
        :param minute:
        :param second:
        '''
        self._hour = hour
        self._minute = minute
        self._second = second

Затем идет работа аналоговых часов.Здесь нам нужно только обратить внимание на краевую задачу процесса работы часов, то есть секунды и минуты нужно обнулять каждые 60, а минуты или часы нужно увеличить на 1, а час нужно делать каждые 24.

 def run(self):
     '''
     模拟时钟的运行
     :return:
     '''
     self._second += 1
     if self._second == 60:
     	self._second = 0
     	self._minute += 1
     	if self._minute == 60:
     		self._minute = 0
     		self._hour += 1
    		 if self._hour == 24:
     			self._hour = 0

Последнее — время отображения.Следует отметить, что три атрибута час, минута и секунда являются целыми числами.%Для форматирования необходимо позвонитьstr()метод, по-видимому, преобразует их из целых чисел в строковые типы, тогда как если вы используетеformat()метод, он вам не нужен.

def show(self):
    '''
    显示时间
    :return:
    '''
    print("{:02d}:{:02d}:{:02d}".format(self._hour, self._minute, self._second))

Простой пример приложения, звоните сюдаtime.sleep()метод, засыпайте на одну секунду каждый раз, когда отображается время, а затем запускайте, установите количество циклов 5 раз.

# 简单时钟例子
clock = Clock(23, 59, 57)
i = 0
while i < 5:
    clock.show()
    sleep(1)
    clock.run()
    i += 1

Выходной результат:

23:59:57
23:59:58
23:59:59
00:00:00
00:00:01
Определите класс, описывающий движение и расстояние между точками

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

Во-первых, это определение основного метода построения.Здесь, как точка на плоскости, атрибутами, которые необходимо определить, являются горизонтальные и вертикальные координаты точки:

# 定义描述平面上点之间的移动和计算距离的类
class Point(object):
    def __init__(self, x=0, y=0):
        '''
        初始的坐标
        :param x:横坐标
        :param y:纵坐标
        '''
        self._x = x
        self._y = y

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

def move_to(self, new_x, new_y):
    '''
    移动到新的坐标
    :param new_x:新的横坐标
    :param new_y:新的纵坐标
    :return:
    '''
    self._x = new_x
    self._y = new_y

Второй — только указать расстояние для перемещения в горизонтальном и вертикальном направлениях:

def move_by(self, dx, dy):
    '''
    移动指定的增量
    :param dx:横坐标的增量
    :param dy:纵坐标的增量
    :return:
    '''
    self._x += dx
    self._y += dy

Затем рассчитайте расстояние между точками, здесь нужно использоватьmathКак импортировать библиотекуsqrt, то есть извлеките квадратный корень:

def distance(self, other):
    '''
    计算与另一个点的距离
    :param other:
    :return:
    '''
    x_dist = self._x - other._x
    y_dist = self._y - other._y
    return sqrt(x_dist ** 2 + y_dist ** 2)

Наконец, конечно же, распечатайте информацию о координатах текущей точки:

 def __str__(self):
     '''
     显示当前点坐标
     :return:
     '''
     return '({},{})'.format(self._x, self._y)

Простой пример приложения

p1 = Point(10, 20)
p2 = Point(30, 5)
print('point1:', p1)
print('point2:', p2)
p1.move_to(15, 25)
print('after move to (15, 25), point1:', p1)
p1.move_by(20, 10)
print('move by (20, 10), point1:', p1)
dist = p1.distance(p2)
print('distance between p1 and p2: ', dist)

Выходной результат:

point1: (10,20)
point2: (30,5)
after move to (15, 25), point1: (15,25)
move by (20, 10), point1: (35,35)
distance between p1 and p2:  30.4138126514911

Ссылаться на:


резюме

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

Кроме того, код этой статьи выложен на мой гитхаб:

GitHub.com/CCC013/py слишком темный…

Добро пожаловать, чтобы обратить внимание на мою общедоступную учетную запись WeChat - машинное обучение и компьютерное зрение, или отсканируйте QR-код ниже, давайте общаться, учиться и прогрессировать вместе!