学习笔记☞python 基础☞面向对象(3) ☞python3

面向对象(3)

issubclass 函数
    issubclass(cls, class_or_tuple)
        判断一个类是否继承自其它的类,如果此类cls 是class 或 tuple中的一个派生子类,则返回True,否则返回False
示例:
class A:
    pass
class B(A):
    pass
class C(B):
    pass
class D(B):
    pass
issubclass(B,A)  # True
issubclass(C,B)  # True
issubclass(D,C)  # False
issubclass(C,(int, str))  # False
封装 enclosure
    封装是指隐藏类的实现细节,让使用者不关心这些细节
    封装的目的是让使用者通过尽可能少的使用实例变量名操作对象

私有属性和方法
    python类中以上下划线'__'开头,不以双下滑先结尾的标识符为私有成员
        私有成员只能被方法调用,不能再子类或其他地方使用
    私有成员有两种:
        私有属性
        私有方法
示例:
class A:
    def __init__(self):
        self.__pl = 100   # 创建私有属性
    def __m1(self):
        print('A类的私有方法被调用!')
    def test(self):
        print(self.__pl)    # 可以访问
        self.__m1   #可以访问
a = A()
# print(a.__pi)   # 出错,不可以访问
# a.__m1  # 出错,在类外不能调用类的私有方法
a.test()    # 用方法来操作私有属性和私有方法
多态 polymorphic
    字面意思:多种状态
    多态是指在有继承/派生关系的类中,调用基类对象的方法,实际能调用子类的覆盖方法的现象叫多态
    多态说明:
        多态调用方法与对象相关,不与类相关
        python的全部对象只有'运行时状态(动态)',没有'C++ / Java'里的'编译时状态(静态)'
多态示例:
class Shape:
    def draw(self):
        pass


class Point(Shape):
    def draw(self):
        print('正在画一个点')


class Circle(Point):
    def draw(self):
        print('正在画一个圆')


def my_draw(s):
    s.draw()  # 调用哪的方法呢?在运行时动态决定调用的方法


s1 = Circle()
s2 = Point()
my_draw(s1)
my_draw(s2)
面向对象的编程语言的特征:
    封装
    继承
    多态
面向对象的语言:
    C++/Java/Python/Swift/C#

多继承:

    多继承是指一个子类继承自两个或两个以上的基类
语法:
    class 类名(超类名1, 超类名1, ...):
        pass
示例
# 此示例示意多继承
class Car:
    def run(self, speed):
        print('汽车以', speed, 'km/h的速度行驶')


class Plane:
    def fly(self, height):
        print('飞机以海拔', height, '米的高度飞行')


class PlaneCar(Car, Plane):
    '''飞行汽车类,继承自Car和Plance'''


p1 = PlaneCar()
p1.fly(10000)
p1.run(299)

多继承的问题(缺陷)
    标识符(名字空间)冲突的问题
        要谨慎使用多继承
示例:
#小张写的一个类A
class A:
    def m(self):
        print('A.m()被调用')
# 小李写的一个类B
class B:
    def m(self):
        print('B.m()'被调用)
# 小王感觉小张和小李写的两个了自己可以用
class AB(A,B):
    pass
ab=AB()
ab.m()  #请问调用谁? # A.m()被调用
多继承的MRO (method Resolution Order)问题
    MRO:方法搜索顺序问题
    python2 使用深度优先算法
    python3 使用广度优先算法
    多继承的类使用 (类名.__mro__) 查看搜索顺序

函数重写 overwrite

    什么是函数重写
        在自定义的类中,通过添加特定的方法,让自定义的类生成的对象(实例)能像内建对象一样进行内建函数操作
对象的字符串函数:
    repr(obj)       返回一个能代表此对象的字符串,通常eval(repr(obj)) == obj
    str(obj)        通过给定的对象返回一个字符串(这个字符串通常是给人阅读的)
        换句话说:repr(obj)返回的字符串是给python用的
                str(obj) 返回的字符串是给人看的
重写方法:
    repr(obj) 函数的重写方法 def __repr__(self)
    str(obj) 函数的重写方法 def __str__(self)
    当对象没有__str__方法时,则返回__repr__(self)的值
示例:
# 此示例示意str(x)函数 和 repr(x)函数的重写方法
class MyNumber:
    def __init__(self, value):
        self.data = value

    def __str__(self):
        print('__str__方法被调用')
        return '数字:%d' % self.data

    def __repr__(self):
        '''此方法共repr(obj)函数调用'''
        return 'MyNumber(%d)' % self.data


n1 = MyNumber(100)
print(str(n1))  # 此句等同于print(n1)
print(n1)
print(repr(n1))  # 他会调用n1.__repr__()方法
内建函数重写
    obj.__abs__()        方法对应          abs(obj)
    obj.__len__()        方法对应          len(obj)
    obj.__reversed__()   方法对应     reversed(obj)
    obj.__round__()      方法对应        round(obj)
示例
# 此示例示意abs(obj)函数的重写方法obj.__abs__()方法的使用
class Myinteger:
    def __init__(self, value):
        self.data = value

    def __repr__(self):
        return 'Myinterger(%d)' % self.data

    def __abs__(self):
        # return 'Myinterger(%d)' % abs(self.data)
        if self.data < 0:
            return Myinteger(-self.data)
        return Myinteger(self.data)
    def __len__(self):
        '''len(x)函数规定只能返回整数值,因此此方法不能返回字符串等其他类型的值'''
        return 1000000

I1 = Myinteger(-10)
print(I1)  # <----此处等同于print(str(I1))
I2 = abs(I1)
print(I2)
print(len(I1))
数值转换函数重写
    obj.__complex__()       对应      complex(obj)
    obj.__int__()           对应      int(obj)
    obj.__float__()         对应      float(obj)
    obj.__bool__()          对应      bool(obj)
示例:
 # 此示例示意 数值类型转换函数重写
class MyNumber:
    '''此类是自定义的类,用于表示自定义数字的类型'''

    def __init__(self, v):
        self.data = v

    def __repr__(self):
        return 'MyNumber(%s)' % self.data

    def __int__(self):
        return int(self.data)


n1 = MyNumber('100')
print('n1=', n1)
print(int(n1))
# print(float(n1))   # 需要实现__float__方法
布尔测试函数的重写
    格式:
        def __bool__(self):
            ...
    作用:
        1、用于bool(obj)函数取值
        2、用于if语句真值表达式中
        3、用于while语句真值表达式中
    说明:
        布尔测试方法的查找顺序是__bool__方法,其次是__len__方法
        如果没有以上方法则返回None
示例:
# 此示例示意 bool 真值测试函数的重写
class MyList:
    '''
    定义一个容器类,用于存储任意类型的数据
    其内部的存储方式用list实现
    '''

    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):
        print('__bool__方法被调用')
        '''此方法用于bool(obj)函数取值,优先取此函数的返回值,此方法用于定义bool(obj)的取值规则'''
        # 规则,所有元素的和为0,则返回False,否则返回True
        return sum(self.data) != 0


myl = MyList([1, -2, 5, -4])
print(myl)
print('bool(myl) =', bool(myl))  # 优先调用__bool__方法,如果没有__bool__方法则调用__len__函数
if myl:
    print('myl 的布尔值为True')
else:
    print('myl 的布尔值为False')

迭代器(高级)

    什么是迭代器
        可以通过 next(obj)函数取值的对象,就是迭代器
    迭代器协议:
        迭代器协议是指对象能够使用next函数获取下一项数据,在没有下一项数据时触发一个StopIteration异常来终止迭代的约定
    迭代器协议的实现方法:
        在类内需要定义__next__(self)方法来实现迭代器协议
    语法形式:
        class MyIteratot:
            def __next__(self):
                迭代器协议
                return 数据
什么是可迭代对象
    是指能用iter(obj)函数返回迭代器的对象(实例)
    可迭代对象的内部定义__iter__(self)方法来返回迭代器对象
示例1
class MyList:
    '''
    定义一个容器类,用于存储任意类型的数据
    其内部的存储方式用list实现
    '''

    def __init__(self, iterable):
        self.data = [x for x in iterable]

    def __repr__(self):
        return 'MyList(%s)' % self.data

    def __iter__(self):  # 有此方法说明myl是迭代器
        '''此方法把MyList类型的对象作为可迭代对象使用此方法需要返回迭代器'''
        return MyIterator(self.data)  # return 迭代器


class MyIterator:
    '''此类定义一个迭代器类,用于生成能够访问MyList对象的迭代器'''

    def __init__(self, lst_data):
        print('迭代器已经创建')
        self.data = lst_data  # 绑定要访问的数据列表
        self.cur_pos = 0  # 是指迭代器的其实位置为0

    def __next__(self):
        '''此方法用来访问可迭代对象的数据,如果没有数据时
        触发StopIteration异常来通知调用者停止迭代,既迭代器协议'''
        # 判断是否索引越界
        if self.cur_pos == len(self.data):
            raise StopIteration
        index = self.cur_pos
        self.cur_pos += 1  # 将当期位置向后移动准备下次获取
        return self.data[index]  # 返回当前位置的数据


myl = MyList([1, -2, 5, -4])
for x in myl:
    print(x)
# 上面for语句等同于下面的语句
it = iter(myl)
while True:
    try:
        x = next(it)
        print(x)
    except StopIteration:
        break
示例2
class MyList:
    '''
    定义一个容器类,用于存储任意类型的数据
    其内部的存储方式用list实现
    '''

    def __init__(self, iterable):
        self.data = [x for x in iterable]

    def __repr__(self):
        return 'MyList(%s)' % self.data

    def __iter__(self):
        self.cur_pos = 0  # 是指迭代器的其实位置为0
        return self  # return 迭代器

    def __next__(self):
        if self.cur_pos == len(self.data):
            raise StopIteration
        index = self.cur_pos
        self.cur_pos += 1  # 将当期位置向后移动准备下次获取
        return self.data[index]  # 返回当前位置的数据


myl = MyList([1, -2, 5, -4])
for x in myl:
    print(x)


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值