欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python面向对象基础(四)

程序员文章站 2022-04-30 13:35:06
...

python面向对象编程最大的乐趣在于“函数重写”,是得我们自定的对象,可以像python内建对象一样,进行函数操作。

一.  函数重写 overwrite

  • 什么是函数重写:在自定义的类内添加相应的特殊方法,让自定义的类生成的对象(实例)像内建对象一样进行函数操作。

二. 对象转字符串的重写方法

  • 对象转字符串函数:repr   &&   str
  1. repr(x):返回一个能代表此对象的表达式字符串,通常eval(repr(obj)) = obj;
  2. str(obj):通过给定对象返回一个字符串(这个字符串通常是给人阅读的);
  3. eval(str):将字符串当成表达式来运行

         python面向对象基础(四)

  • 对象转字符串的重写方法:(类似于java中重写toString()方法)
  1. repr()函数的重写方法

        def __repr__(self):
            ...
            return 字符串   # 返回的对象必须是字符串
     2. str()函数的重写方法:
        def __str__(self):
            ...
            return 字符串  # 返回的对象必须是字符串

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

  1. str(obj) 函数先查找obj.__str__()调用此方法,并返回结果
  2. 如果obj.__str__这个方法不存在,则调用obj.__repr__()方法并返回结果;
  3. 如果obj.__repr__()方法不存在,则调用object类的__repr__实例方法打印<__main__.MyNumber object at xxx> 
"""对象转字符串的重写方法"""


class MyNumber:
    def __init__(self, value):
        self.data = value

    def __str__(self):
        """此方法继承自父类object"""
        return "自定义数据MyNumber(%d)" % self.data

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


if __name__ == "__main__":
    print(MyNumber(100))
    print(MyNumber(100).__str__())
    print(str(MyNumber(100)))

    print(repr(MyNumber(200)))
    print(MyNumber(200).__repr__())

    print(eval(repr(MyNumber(300))))

运行结果:

python面向对象基础(四)

三. 内建函数重写

重写方法 调用
__abs__ abs(obj)
__len__ len(obj)
__reversed__ reversed(obj)
__round__ round(obj)

示例:

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

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

    def __str__(self):
        return '%d' % self.data

    def __abs__(self):
        """此方法用于制定abs(obj)函数取值时返回的结果"""
        if self.data < 0:
            return MyInteger(-self.data)
        return MyInteger(self.data)

    def __len__(self):
        return len(self.__abs__().__str__())

    def __reversed__(self):
        return MyInteger(self.data * -1)


print(MyInteger.__mro__)
num = MyInteger(-100)
# 等同于print(str(i1))
print("自定义的整数:{}".format(num))
# dir(object)没有__abs__方法
print("{}的绝对值为{}".format(repr(num), abs(num)))
print("{}的长度为{}".format(repr(num), len(num)))
print("{}反转后为{}".format(repr(num), repr(reversed(num))))

运行结果:

python面向对象基础(四)

四. 数值转换函数重写

重写方法 函数调用
__complex__ complex(obj)
__int__ int(obj)
__float__ float(obj)
__bool__ bool(obj)
  • 布尔测试函数重写
  1. 格式:def __bool__(self):
  2. 作用:bool(obj)函数取值   |  if语句真值表达式  |  while语句的值表达式
  3. 说明:
    1. 当自定义类内有__bool__(self)方法时,以此方法的返回值作为bool(obj)的返回值;
    2. 当不存在__bool__(self)方法时,根据__len__(self)方法的返回值是否为0来测试bool值;
    3. 当再不存在__len__(self)方法时,返回True;
class MyList:
    """__bool__方法的重写方法及用法"""
    def __init__(self, iterable=()):
        self.data = [x for x in iterable]

    def __repr__(self):
        print('__repr__方法被调用')
        return 'MyList(%s)' % self.data

    def __len__(self):
        print('__len__方法被调用')
        return len(self.data)

    def __bool__(self):
        """此方法用来制定一个bool(x)返回的规则"""
        print("__bool__方法被调用")
        if len(self.data) == 0:
            return False
        for x in self.data:
            if x:
                return True
        return False


if __name__ == "__main__":
    myl = MyList([1, -2, 3, -4])
    print("my1:{}, {}".format(myl, bool(myl)))

    my2 = MyList([0, 0.0, False])
    print("my2:{}, {}".format(my2, bool(my2)))

运行结果1:

python面向对象基础(四)

运行结果2:注释掉__bool__运行

python面向对象基础(四)

运行结果3:注释掉__bool__和__len__方法运行

python面向对象基础(四)

五. 自定义类实现迭代器功能

  • 什么是迭代器:可以通过next函数取值的对象称为迭代器;
  • 迭代器协议:对象能够使用next函数获取下一个数据,在没有下一项数据时触发一个Stopiteration异常来终止迭代的约定; 

       python面向对象基础(四)

  • 迭代器的实现办法:__next__(self) 方法用来实现迭代器协议;

        python面向对象基础(四)

  • 什么是可迭代对象:是指能用iter(obj)返回迭代器对象,可迭代对象内部要定义__iter__(self)来返回迭代器对象;

       python面向对象基础(四)

  • 可迭代对象的语法形式:

        class MyIterable:
            def __iter__(self):
                语句块
                return 迭代器

示例:

class MyIterator:
    """用自定义的类MyIterator实现迭代器"""
    def __init__(self, start, stop, step):
        # 用来记录迭代器的起始位置和当前位置
        self.start = start
        self.stop = stop
        self.step = step

    def __next__(self):
        """实现迭代器协议"""
        if self.start >= self.stop:
            raise StopIteration
        # 将要返回的数据存入一个变量
        r = self.start
        self.start += self.step  # 迭代器后移
        return r


class MyRange:
    """使用自定义的类MyRange实现可迭代对象"""
    def __init__(self, start, stop=None, step=1):
        if stop is None:
            stop = start
            start = 0
        self.start = start
        self.stop = stop
        self.step = step

    def __repr__(self):
        return 'MyRange(%d,%d,%d)' % (self.start, self.stop, self.step)

    def __iter__(self):
        """用于将MyRange类型创建的对象当做可迭代对象"""
        # 返回值必须为一个迭代器
        return MyIterator(self.start, self.stop, self.step)


if __name__ == "__main__":
    L = [x for x in MyRange(5)]
    print(L)

    R = iter(MyRange(1, 6, 2))
    while True:
        try:
            print(next(R))
        except StopIteration:
            break

运行结果:

python面向对象基础(四)

相关标签: 特殊函数重写