python 浅浅盘一盘“类”(二:继承)

1. 单继承

代码编写过程中,重复的地方肯定越少越好,继承就是一个能够有效减少重复的一个方法,这里主要讲述三点:

  1. 继承的基本语法
  2. 方法的重写
    父类的方法实现不能满足子类的需求。
  3. 对父类方法扩展
    子类的方法实现中包含父类的方法实现。

最后我用实现二帧差法和三帧差法来最为实例。


1.1. 继承的基本语法

class 类名(父类名):
	pass

1.2. 方法的重写

重写的英文名字为override,可以理解为把父类的方法整个覆盖掉。其具体实现方式:在子类中定义了一个和父类同名的方法并且实现。

1.3. 对父类方法扩展

如果在子类中需要部分父类的方法,那么就可以使用扩展功能。
就可以使用扩展的方式:

  1. 在子类中 重写 父类的方法
  2. 在需要的位置使用 super().父类方法 来调用父类方法的执行
  3. 代码其他的位置针对子类的需求,编写子类特有的代码实现

关于 super
在 Python 中 super 是一个 特殊的类
super() 就是使用 super 类创建出来的对象,最常使用的场景就是在 重写父类方法时,调用 在父类中封装的方法实现。
python 子类继承父类的__init__方法


以上内容参考python 黑马程序员。按我自己的理解,在子类中一旦出现与父类同名的方法,就发生重写,此时子类中相当于开辟了一个新的区域用于存放重写的代码。而扩展则是调用一遍父类的方法,然后再执行子类方法里的代码。

1.4.代码实例

import cv2
import numpy as np


class SlideWindow:
    def __init__(self, window_size, step_size):
        self.window_size = window_size
        self.step_size = step_size
        if self.step_size >= self.window_size:
            print('SlideWindow error')
        self.val_list = []

    def update_window_val(self, val):
        self.val_list.append(val)
        if len(self.val_list) > self.window_size:
            for i in range(0, self.step_size):
                self.val_list.pop(0)

        return self.val_list

    def clear(self):
        self.val_list.clear()


class FrameDifferenceProcess(object):
    def __init__(self):  # 初始化一个滑动窗口来记录帧的数据
        self.window_type = 2
        self.image_process_slide_window = SlideWindow(self.window_type, 1)
        self.diff_frame_flag = False

    def process(self, frame):  # 进行帧差计算
        self.frame_copy = np.copy(frame)
        self.frame_window = self.image_process_slide_window.update_window_val(self.frame_copy)

        if len(self.frame_window) == self.window_type:
            gray_image_1 = cv2.cvtColor(self.frame_window[0], cv2.COLOR_BGR2GRAY)
            gray_image_1 = cv2.GaussianBlur(gray_image_1, (3, 3), 0)
            gray_image_2 = cv2.cvtColor(self.frame_window[1], cv2.COLOR_BGR2GRAY)
            gray_image_2 = cv2.GaussianBlur(gray_image_2, (3, 3), 0)

            d_frame = cv2.absdiff(gray_image_1, gray_image_2)
            ret, self.d_frame = cv2.threshold(d_frame, 15, 255, cv2.THRESH_BINARY)  # 阈值要高
            self.dframe_modification()

    def dframe_modification(self):  # 对帧差完成后的图像略作图像学修改
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
        self.d_frame = cv2.dilate(self.d_frame, kernel, iterations=7)   # 最终的三帧差结果
        if not np.any(self.d_frame):
            self.diff_frame_flag = True

    def clear(self):
        self.image_process_slide_window.clear()


class TwoFrameDifferenceProcess(FrameDifferenceProcess):
    pass


class ThreeFrameDifferenceProcess(FrameDifferenceProcess):
    def __init__(self):
        super(ThreeFrameDifferenceProcess, self).__init__()
        self.window_type = 3
        self.image_process_slide_window = SlideWindow(self.window_type, 1)

    def process(self, frame):
        # print("在进行三帧差法")
        self.frame_copy = np.copy(frame)
        self.frame_window = self.image_process_slide_window.update_window_val(self.frame_copy)

        if len(self.frame_window) == 3:
            gray_image_1 = cv2.cvtColor(self.frame_window[0], cv2.COLOR_BGR2GRAY)
            gray_image_1 = cv2.GaussianBlur(gray_image_1, (3, 3), 0)
            gray_image_2 = cv2.cvtColor(self.frame_window[1], cv2.COLOR_BGR2GRAY)
            gray_image_2 = cv2.GaussianBlur(gray_image_2, (3, 3), 0)
            gray_image_3 = cv2.cvtColor(self.frame_window[2], cv2.COLOR_BGR2GRAY)
            gray_image_3 = cv2.GaussianBlur(gray_image_3, (3, 3), 0)

            d1_frame = cv2.absdiff(gray_image_1, gray_image_2)
            ret, d1_frame = cv2.threshold(d1_frame, 15, 255, cv2.THRESH_BINARY)  # 阈值要高
            d2_frame = cv2.absdiff(gray_image_2, gray_image_3)
            ret, d2_frame = cv2.threshold(d2_frame, 15, 255, cv2.THRESH_BINARY)
            self.d_frame = cv2.bitwise_and(d1_frame, d2_frame)

            super().dframe_modification()

2. 多继承

2.1. 基本语法

class 子类名(父类名1,父类名2...)
	pass

3. 关于继承的思考

  1. 父类中属性的变化会影响子类的值吗?
  2. 没有实例化前父类和子类的内存地址与所占空间?
  3. 实例化后父类和子类的所占地址和所占空间?
  4. 实例化后父类和子类方法地址是否相同?
import sys
class A:
    def __init__(self):
        self.num1 = 1

    def change_num(self, num):
        self.num1 = num


class B(A):
    pass


class C:
    def __init__(self, cc):
        self.c = cc
        self.c2 = 3


# 地址不同
print(id(A))
print(id(B))
# 地址相同
print(id(A.change_num))
print(id(B.change_num))
# 相同 1064
print(sys.getsizeof(A))
print(sys.getsizeof(B))
print(sys.getsizeof(C))

a = A()
b = B()
c = C(2)
# 相同 48
print(sys.getsizeof(a))
print(sys.getsizeof(b))
print(sys.getsizeof(c))

# 不同
print(id(a))
print(id(b))
# 相同
print(id(a.num1))
print(id(b.num1))
# 相同
print(id(a.change_num))
print(id(b.change_num))
# 值相同
print(a.num1)
print(b.num1)


a.change_num(2)
# 不同
print(a.num1)  # 2
print(b.num1)  # 1
# 不同
print(id(a.num1)) 
print(id(b.num1))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙橙小狸猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值