(D19)Python-封装、多态、多继承、重写

本文深入讲解面向对象编程的三大核心特性:封装、继承和多态。详细解释了封装如何通过私有属性和方法隐藏实现细节,多态如何通过方法重写实现不同类之间的灵活调用,以及继承和多继承的基本概念与应用。


封装 enclosure

  • 封装是指隐藏类的实现细节,让使用者不用关心这些细节
  • 封装的目的是让使用者通过尽可能少的方法(或属性)操作对象

私有属性和方法:

  • python类中以双下划线(’__’)开头,不以双下划线结尾的标识符为私有成员,私有成员只能用此类的方法进行访问和修改

示例1:


# 此示例示意用私有属性和私有方法来进行封装
class A:
    def __init__(self):
        self.__p1 = 100  # 创建私有属性,此属性在类外无法访问
 
    def __m1(self):  # 私有方法
        print("__m1 私有方法被调用")
 
    def infos(self):
        print("A类的infos访问的__p1属性是:", self.__p1)
        self.__m1()  # 调用自己的私有方法
    
a = A()
# print(a.__p1)  # 出错
a.infos()
# a.__m1()  # 当前主模块不能调用A类的私有方法


多态 polymorphic

  • 什么是多态:

    • 字面意思: 多种状态
  • 状态:

    • 静态(编译时状态)
    • 动态(运行时状态)
  • 多态是指在有继承/派生关系的类中,调用基类对象的方法,调用基类对象的方法,实际能调用子类的覆盖方法的现象叫多态

  • 说明:

    • 多态调用的方法与对象相关,不与类型相关
    • python全部对象都只有运行时状态(动态)
    • 没有"c++语言"里编译时状态(静态)

示例2:


# 此示例示意python的多态(动态)
class Shape:
    '''图形'''
    def draw(self):
        print("Shape的draw() 被调用")
 
class Point(Shape):
    def draw(self):
        print("正在画一个点")
 
class Circle(Point):
    def draw(self):
        print("正在画一个圆")
        
def my_draw(s):
    s.draw()  # s.draw调用谁是在运行时由s的类型动态决定
              # 此处显示出运行时状态
 
shape1 = Circle()
shape2 = Point()
my_draw(shape1)
my_draw(shape2)
 
L = [Point(), Circle(), Point(), Point(), Circle()]
 
for s in L:

面向对象的编程语言的特征

封装
继承/派生
多态

多继承 multiple inheritance

  • 多继承是指一个子类继承自两个或两个以上的基类

语法:
- class 类名(基类名1,基类名2,…)
说明:

  • 一个子类同时继承自多个父类,父类中的方法可以同时被继承下来
    如果两个父类中有同名的方法,则在子类中又没有覆盖此方法时,
    调用结果难以确定
    示例3:

# 此示例示意多继承的语法和用法
class Car:
    def run(self, speed):
        print('车正在以', speed, '公里/小时的速度行驶')
 
class Plane:
    def fly(self, height):
        print('飞机以海拔', height, '米的高空飞行')
 
class PlaneCar(Plane, Car):
    '''PlaneCar类同时继承是Plane和 Car类'''
 
p1 = PlaneCar()
p1.fly(10000)

多继承的问题(缺陷)

  • 标识符(名字空间)冲突问题
  • 要谨慎使用多继承

多继承的MRO(Method Resolution Order)等问题

  • 类的__mro__属性:
    • 作用:
      • 用来记录属性(或方法)的查找顺序

函数重写 overwrite

什么是函数重写

  • 在自定义的类内添加相应的方法,让自定义的类生成的对象(实例)
  • 像内建对象一样进行函数操作

对象转字符串函数:

  • repr(x) 返回一个能代表此对象的表达式字符串,通常:
    • eval(repr(obj)) = obj
  • str(obj) 通过给定对象,返回一个字符串(这个字符串通常是给人阅读的)

示例4:

# 此示例示意repr函数和str函数的不同
s = "I'm Teacher"
print(str(s))  
print(repr(s))
 
 
class MyNumber:
    def __init__(self,value):
        self.data = value
    def __str__(self):
        print("正在调用__str__方法,转换为普通字符串")
        s = "自定义数据%d" % self.data
        return s
  
    def __repr__(self):
        return 'MyNumber(%d)' % self.data
 
n1 = MyNumber(100)
print(str(n1))
print(repr(n1))


# 此示例示意自定义的对象转为python内键的数字类型
class MyNumber:
    def __init__(self, v):
        self.data = v
    def __repr__(self):
        return "MyNumber(%d)" % self.data
    def __int__(self):
        return int(self.data)
 
n1 = MyNumber(100.5)
n = int(n1)  # 自定义类型转为整数, 出错!!!
print(n)

str(obj) 函数调用方法说明:

  1. str(obj) 函数先查找obj.__str__()方法,调用此方法并返回结果
  2. 如果obj.__str__() 方法不存在,则调用obj.__repr__()方法并返回结果
  3. 如果obj.__repr__方法不存在,则调用object类的__repr__实例方法显示
    <__main__.MyNumber object at xxx>格式的字符串

内建函数重写

    __abs__         abs(obj) 函数调用
    __len__         len(obj) 函数调用
    __reversed__   reversed(obj) 函数调用
    __round__       round(obj) 函数调用

示例5


# 此示例示意 abs 和len方法的重写方法
 
class MyInteger:
    def __init__(self, v):
        self.data = v
 
    def __repr__(self):
        return 'MyInteger(%d)' % self.data
 
    def __abs__(self):
        '''此方法用于制定abs(obj) 函数取值时返回的结果'''
        if self.data < 0:
            # 用-self.data 创建一个新的对象返回回去
            t = MyInteger(-self.data)
            return t
        return MyInteger(self.data)
 
i1 = MyInteger(-100)
 
print(i1)  # 等同于print(str(i1)) 
n = abs(i1)
print(n)  # MyInteger(100)
 
i2 = MyInteger(200)
print(abs(i2))  # MyInteger(200)

数值转换函数重写

    __complex__     coplex(obj)  函数调用
    __int__         int(obj)  函数调用
    __float__       float(obj)  函数调用
    __bool__        bool(obj)  函数调用

示例6


# 此示例示意自定义的对象转为python内键的数字类型
class MyNumber:
    def __init__(self, v):
        self.data = v
    def __repr__(self):
        return "MyNumber(%d)" % self.data
    def __int__(self):
        return int(self.data)
 
n1 = MyNumber(100.5)
n = int(n1)  # 自定义类型转为整数, 出错!!!
print(n)

布尔测试函数重写

  • 格式:
    • def bool(self):

作用:

  • 用于bool(obj)函数取值
  • 用于if语句真值表达式中
  • 用于while语句的值表达式中

说明:

  • 1.当自定义类有__bool__(self)方法时,以此方法的返回值作为bool(obj)的返回值
    1. 当不存在__bool__(self)方法时,bool(x)返回__len__(self)方法的返回值是否为零来测试布尔值
  • 3.当再不存在__len__(self)方法时,则直接返回True

示例7:

# 此示例示意__bool__方法的重写方法及用法
 
class MyList:
    def __init__(self, iterable=()):
        self.data = [x for x in iterable]
 
    def __repr__(self):
        return "MyList(%s)" % self.data
 
    def __len__(self):
        print("__len__被调用")
        return len(self.data)
    def __bool__(self):
        '''此方法用来制定一个bool(x) 返回的规则'''
        # 如果没有任何元素返回False
        print("__bool__方法被调用")
        if len(self.data) == 0:
            return False
        for x in self.data:
            if x:
                return True
        return False
 
myl = MyList([1, -2, 3, -4])
# myl = MyList()
print(myl)
print(bool(myl))  # False
print(len(myl))
 
myl1 = MyList([0, 0.0, False, None])    
print(bool(myl1))  # False
 
myl2 = MyList([0, 1, 2])
print(bool(myl2))  # True
### 查询 PC4D19SNIP0F 的封装类型及相关信息 对于查询具体元件型号 `PC4D19SNIP0F` 的封装类型及其数据表,以下是相关信息: #### 1. 型号解析 `PC4D19SNIP0F` 是一种特定的电子元器件型号。通常情况下,这种类型的编号可能代表某种集成电路(IC)、功率晶体管或其他半导体设备。然而,具体的封装形式需要通过官方的数据手册或制造商的技术文档来确认。 #### 2. 封装类型的可能性分析 根据类似的 IC 或功率器件命名规则,以下是一些常见的可能性: - **TO系列封装**:如果该型号属于功率晶体管,则可能是 TO-220、TO-247 或其他 TO 系列封装[^1]。 - **SMD/SMT封装**:如果是表面贴装器件(Surface Mount Device),则可能是 SOIC、QFN、LGA 或 BGA 类型。 - **芯片级封装(CSP)**:某些高性能或小型化设计可能会采用 CSP 技术。 需要注意的是,仅凭型号无法完全判断其封装类型,因为同一型号在不同厂商下可能存在差异。 #### 3. 获取数据表的方法 为了获取更详细的封装信息和其他技术参数,建议采取以下方法: - 访问原厂官网:查找生产该型号的具体公司网站并下载对应的数据表(Datasheet)。 - 利用在线数据库工具:例如 Octopart、Mouser Electronics 或 Digi-Key 提供了丰富的元器件检索功能。 - 参考第三方资源库:一些开源硬件社区也可能分享过关于此类产品的资料。 下面是一个简单的 Python 脚本示例,可以帮助自动化搜索过程中的部分工作流程: ```python import requests from bs4 import BeautifulSoup def search_component(component_name): url = f"https://www.mouser.com/Search/Refine?Keyword={component_name}" response = requests.get(url) if response.status_code == 200: soup = BeautifulSoup(response.text, 'html.parser') results = soup.find_all('div', {'class': 'product-details'}) for result in results[:5]: # 显示前五个匹配项 title = result.h2.a['title'] link = result.h2.a['href'] print(f"{title}: {link}") search_component("PC4D19SNIP0F") ``` 此脚本利用 Mouser Electronics API 接口实现基本爬取操作,并展示初步结果链接以便进一步查阅详情页面内容。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值