用于类的函数 issubclass(cls,class_or_tuple)

判断一个类是否继承自其他的类,如果此类cls是class或tuole中的一个派生(子类)则返回True,否则返回False

封装 enclosure

封装的目的是让使用者尽可能少的引用实例变量(属性)进行操作

私有属性:python类中,以双下划线‘__’开头,不以双下划线结尾的标识符为私有成员,在类的外部无法直接访问。

  1. class A:
  2. def __init__(self):
  3. self.__p1 = 100 #__p1为私有属性,在类的外部不可访问
  4.  
  5. def test(self):
  6. print(self.__p1) # 可以访问
  7. self.__m1() # A类的方法可以调用A类的私有方法
  8.  
  9. def __m1(self):
  10. '''我是私有方法,只有我自己的类中的方法才能调用我哦'''
  11. print("我是A类的__m1方法!")
  12.  
  13. a = A() # 创建对象
  14. # print(a.__p1) # 在类外看不到__p1属性,访问失败!
  15. a.test()
  16. # a.__m1() # 出错.无法调用私有方法

__私有属性

多态 polymorphic

多态是指在继承\派生关系的类中,调用基类对象的方法,实际能调用子类的覆盖版本方法的现象叫多态

  1. class Shape:
  2. def draw(self):
  3. print("Shape.draw被调用")
  4.  
  5. class Point(Shape)
  6. def draw(self):
  7. print('正在画一个点')
  8.  
  9. class Circle(Point):
  10. def draw(self):
  11. print("正在画一个圆")
  12.  
  13. def my_draw(s):
  14. s.draw() # 此处显示出多态中的动态
  15.  
  16. s1 = Circle()
  17. s2 = Point()
  18. my_draw(s1) # 调用Circle里的draw 正在画一个圆
  19. my_draw(s2) # 调用Point里的draw 正在画一个点

多态

多继承 multiple inheritance

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

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

  1. class Car:
  2. def run(self, speed):
  3. print("汽车以", speed, '公里/小时的速度行驶')
  4.  
  5. class Plane:
  6. def fly(self, height):
  7. print("飞机以海拔", height, '的高度飞行')
  8.  
  9. class PlaneCar(Car, Plane):
  10. '''PlaneCar同时继承自汽车类和飞机类'''
  11.  
  12. p1 = PlaneCar()
  13. p1.fly(10000)
  14. p1.run(300)

多继承

多继承的问题(缺陷):名字冲突问题,要谨慎使用多继承(会先使用第一个继承的基类

  1. class A:
  2. def m(self):
  3. print("A.m()被调用")
  4.  
  5. class B:
  6. def m(self):
  7. print('B.m()被调用')
  8.  
  9. class AB(A, B):
  10. pass
  11.  
  12. ab = AB()
  13. ab.m() # A.m()被调用

命名冲突

继承的MRO(Method Resolution Order)问题

  的__mro__属性用来记录继承方法的查找顺序

  1. class A:
  2. def m(self):
  3. print("A.m")
  4. class B(A):
  5. def m(self):
  6. print("B.m")
  7. class C(A):
  8. def m(self):
  9. print("C.m")
  10. class D(B, C):
  11. '''d类继承自B,C'''
  12. def m(self):
  13. print("D.m")
  14. d = D()
  15. print(D.__mro__)
  16. #(<class '__main__.D'>,
  17. # <class '__main__.B'>,
  18. # <class '__main__.C'>,
  19. # <class '__main__.A'>,
  20. # <class 'object'>)
  21. d.m() # 调用方法的顺序如上所示

多继承顺序

  1. class A:
  2. def m(self):
  3. print("A.m")
  4. class B(A):
  5. def m(self):
  6. print("B.m")
  7. super().m()
  8. class C(A):
  9. def m(self):
  10. print("C.m")
  11. super().m()
  12. class D(B, C):
  13. '''d类继承自B,C'''
  14. def m(self):
  15. print("D.m")
  16. super().m()
  17. d = D()
  18. d.m() # 调用方法的顺序是什么?
  19.  
  20. for x in D.__mro__:
  21. print(x)
  22.  
  23. # D.m
  24. # B.m
  25. # C.m
  26. # A.m
  27. # <class '__main__.D'>
  28. # <class '__main__.B'>
  29. # <class '__main__.C'>
  30. # <class '__main__.A'>
  31. # <class 'object'>

多继承顺序

函数重写

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

对象转字符串函数:

  repr(obj) 返回一个能代表此对象的表达式字符串,通常eval(repr(obj))==obj (这个字符串通常是给python解释执行器运行用的)

对象转字符串函数的重写方法

  reper(obj)函数的重写方法:  def__repr__(self):

                    return 能够表达self内容的字符串

  str(obj)函数的重写方法:  def__str__(self):

                    return 人能看懂的字符串

  1. class MyNumber:
  2. def __init__(self, value):
  3. self.data = value
  4. def __str__(self):
  5. print("__str__被调用")
  6. return "数字: %d" % self.data
  7. def __repr__(self):
  8. print("__repr__被调用")
  9. return 'MyNumber(%d)' % self.data
  10. n1 = MyNumber(100)
  11. # print(str(n1)) # 调用 n1.__str__(self);__str__被调用;数字: 100
  12. # print(repr(n1)) #__repr__被调用 MyNumber(100)
  13. print(n1) # ;__str__被调用;数字: 100
  14. # n2 = eval("MyNumber(100)")
  15. # print(n2) #__str__被调用;数字: 100

重写方法

说明:

1、str(obj)函数先调用obj.__str__()方法,调用此方法并返回字符串

2、如果obj没有__str__()方法,则调用obj.__repr__()方法返回的字符串

3、如果obj没有__repr__()方法,则调用object类的__repe__()实例方法显示<xxxx>格式的字符串

数值转换函数的重写

  def __complex__(self)  complex(obj) 函数调用
  def __int__(self)    int(obj) 函数调用
  def __float__(self)   float(obj) 函数调用
  def __bool__(self)    bool(obj) 函数调用

  1. '''此示例示意自定义的类MyNumber能够转成为数值类型'''
  2. class MyNumber:
  3. def __init__(self, v):
  4. self.data = v
  5. def __repr__(self):
  6. return "MyNumber(%d)" % self.data
  7. def __int__(self):
  8. '''此方法用于int(obj) 函数重载,必须返回整数
  9. 此方法通常用于制订自义定对象如何转为整数的规则
  10. '''
  11. return 10000
  12.  
  13. n1 = MyNumber(100)
  14. print(type(n1))
  15. # if n1 == 100:
  16. # print("n1 == 100")
  17. n = int(n1)
  18. print(type(n))
  19. print(n)

自定义类可以转成数值类型

  1. <class '__main__.MyNumber'>
  2. <class 'int'>
  3. 10000

结果

内建函数的重写
  __abs__      abs(obj)
  __len__      len(obj)
  __reversed__   reversed(obj)
  __round__     round(obj)

  1. # 自定义一个MyList类,与系统内建的类一样,
  2. # 用来保存有先后顺序关系的数据
  3.  
  4. class MyList:
  5. '''自定义列表类'''
  6. def __init__(self, iterator=[]):
  7. self.data = [x for x in iterator]
  8.  
  9. def __repr__(self):
  10. return "MyList(%r)" % self.data
  11.  
  12. def __abs__(self):
  13. # return MyList([abs(x) for x in self.data])
  14. # 上一句语句可以用如下生成表达式代替已防止过多占内存
  15. return MyList((abs(x) for x in self.data))
  16.  
  17. def __len__(self):
  18. # return self.data.__len__()
  19. return len(self.data)
  20.  
  21. myl = MyList([1, -2, 3, -4])
  22. print(myl)
  23. print(abs(myl)) # MyList([1, +2, 3, +4])
  24. print("原来的列表是:", myl)
  25.  
  26. myl2 = MyList(range(10))
  27. print(myl2)
  28. print('myl2的长度是:', len(myl2))
  29. print('myl的长度是: ', len(myl))
  1. MyList([1, -2, 3, -4])
  2. MyList([1, 2, 3, 4])
  3. 原来的列表是: MyList([1, -2, 3, -4])
  4. MyList([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
  5. myl2的长度是: 10
  6. myl的长度是: 4

结果

布尔测试函数的重写

  格式 def __bool__(self):
    ...
作用:
  用于bool(obj) 函数取值
  用于if语句真值表达式中
  用于while语句真值表达式中
说明:
  1. 优先调用__bool__方法取值
  2. 如果不存在__bool__方激动 ,则用__len__()方法取值后判断是否为零值,如果不为零返回True,否则返回False
  3. 如果再没有__len__方法,则直接返回True

  1. class MyList:
  2. '''自定义列表类'''
  3. def __init__(self, iterator=[]):
  4. self.data = [x for x in iterator]
  5.  
  6. def __repr__(self):
  7. return "MyList(%r)" % self.data
  8.  
  9. def __bool__(self):
  10. print("__bool__方法被调用!")
  11. return False
  12.  
  13. # def __len__(self):
  14. # print("__len__被调用")
  15. # return len(self.data)
  16.  
  17. myl = MyList([1, -2, 3, -4])
  18. print(bool(myl)) # False
  19. if myl:
  20. print("myl 是真值")
  21. else:
  22. print("myl 是假值")
  1. __bool__方法被调用!
  2. False
  3. __bool__方法被调用!
  4. myl 是假值

结果

迭代器(高级)

可以通过next(it) 函数取值的对象就是迭代器
迭代器协议:迭代器协议是指对象能够使用next函数获取下一项数据,在没有下一项数据时触发一个StopIterator来终止迭代的约定
实现方法:类内需要有 __next__(self) 方法来实现迭代器协议
语法形式:
  class MyIterator
    def __next__(self):
      迭代器协议的实现
      return 数据

可迭代对象是指能用iter(obj) 函数返回迭代器的对象(实例),可迭代对象内部一定要定义__iter__(self)方法来返回迭代器

可迭代对象的语法形式:
  class MyIterable:
    def __iter__(self):
      语句块
      return 迭代器

  1. # 此示例示意可迭代对象和迭代器的定义及使用方式:
  2. class MyList:
  3. def __init__(self, iterator):
  4. '''自定义列表类的初始化方法,此方法创建一个data实例
  5. 变量来绑定一个用来存储数据的列表'''
  6. self.data = list(iterator)
  7.  
  8. def __repr__(self):
  9. '''此方法了为打印此列表的数据'''
  10. return 'MyList(%r)' % self.data
  11.  
  12. def __iter__(self):
  13. '''有此方法就是可迭代对象,但要求必须返回迭代器'''
  14. print("__iter__方法被调用!")
  15. return MyListIterator(self.data)
  16.  
  17. class MyListIterator:
  18. '''此类用来创建一个迭代器对象,用此迭代器对象可以迭代访问
  19. MyList类型的数据'''
  20. def __init__(self, iter_data):
  21. self.cur = 0 # 设置迭代器的初始值为0代表列表下标
  22. # it_data 绑定要迭代的列表
  23. self.it_data = iter_data
  24.  
  25. def __next__(self):
  26. '''有此方法的对象才叫迭代器,
  27. 此方法一定要实现迭代器协议'''
  28. print("__next__方法被调用!")
  29. # 如果self.cur已经超出了列表的索引范围就报迭代结束
  30. if self.cur >= len(self.it_data):
  31. raise StopIteration
  32. # 否则尚未迭代完成,需要返回数据
  33. r = self.it_data[self.cur] # 拿到要送回去的数
  34. self.cur += 1 # 将当前值向后移动一个单位
  35. return r
  36.  
  37. myl = MyList([2, 3, 5, 7])
  38. print(myl)
  39.  
  40. for x in myl:
  41. print(x) # 此处可以这样做吗?
  42.  
  43. # it = iter(myl)
  44. # x = next(it)
  45. # print(x)
  46. # x = next(it)
  47. # print(x)
  48. # x = next(it)
  49. # print(x)
  1. MyList([2, 3, 5, 7])
  2. __iter__方法被调用!
  3. __next__方法被调用!
  4. 2
  5. __next__方法被调用!
  6. 3
  7. __next__方法被调用!
  8. 5
  9. __next__方法被调用!
  10. 7
  11. __next__方法被调用!

结果

python 多态、多继承、函数重写、迭代器的更多相关文章

  1. python -- 面向对象编程(继承、重写)

    一.继承 子类可以继承父类的所有公有成员,但不能直接访问父类的私有成员,只能通过父类的公有方法间接访问私有属性或私有方法. 如: class DerviedClassName(BaseClassNam ...

  2. python: 多态与虚函数;

    通过python的abc模块能够实现虚函数: 首先在开头from abc import   ABCMeta, abstractmethod 例子 : #!/usr/bin/python #coding ...

  3. c++中的函数重载、函数重写、函数重定义

    目录 一.函数重载 二.函数重写 三.函数重定义 为了更加深刻的理解 函数重载.重写.重定义,我们可以带着如下这两个问题去思考: 1.子类中是否可以定义父类中的同名成员?为什么? 可以,因为子类与父类 ...

  4. Python全栈工程师(多继承、函数重写)

    ParisGabriel                每天坚持手写  一天一篇  决定坚持几年 为了梦想为了信仰    开局一张图 Python人工智能从入门到精通 补充: 对象 --------- ...

  5. Python面向对象:继承和多态

    继承与多态简介: 继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写. 动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的. ...

  6. Python入门之面向对象的多态和继承

    本章内容 Python面向对象的多态和继承对比 ========================================= 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的 ...

  7. python入门18 继承和多态

    继承:子类继承父类的属性和方法  class 子类名(父类1,父类2) 多态:子类重写父类的方法 判断对象是否是某个类的实例:  isinstance(object,class) 父类-汽车类 #co ...

  8. 【转载】 C++多继承中重写不同基类中相同原型的虚函数

    本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: ...

  9. [转]Java中继承、多态、重载和重写介绍

    什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承.多态.重载和重写. 继承(inheritance) 简单的说,继承就是在一个现有类型的基础上 ...

随机推荐

  1. 详解Python中re.sub--转载

    [背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...

  2. Qt5发布错误01

    1.Qt5+VS2013兼容XP方法 (http://www.qtcn.org/bbs/apps.php?q=diary&a=detail&did=2047&uid=15538 ...

  3. 用Python操作Named pipe命名管道,实用做法——os.read 或 os.write

    https://blog.csdn.net/mayao11/article/details/50618598

  4. How To Use Amazon MWS To Download Unshipped Order Reports

    文章来源:http://www.samswiches.com/2011/02/how-to-use-amazon-mws-to-download-unshipped-order-reports/ ac ...

  5. thinkphp3.2验证码在服务器上显示不出来

    ThinPHP3.2 验证码 在本地服务器访问可以显示,上传到服务器就不能访问了 /**** * 验证码 */ function code() { $config=array( 'fontSize'= ...

  6. Digitalocean+DNSPod搭建Meteor.js博客Telescope.js

    1. 什么是Meteor.js 基于Node.js的一个快速开发平台. 简言之,Node.js>Meteor.js 对等于Ruby>Ruby on Rails的关系. 官网:http:// ...

  7. poj3666&&bzoj1592

    题解: 和bzoj1367差不多 然后a[i]-i不用加 然后我再另一个地方加了这句话 然后poj ac,bzoj wa poj数据水啊 代码: #include<cstdio> #inc ...

  8. Kotlin Reference (十) Interfaces

    most from reference 接口 Kotlin中的接口非常类似于Java8,它们可以包含抽象方法的声明以及方法实现.与抽象类不同的是接口不能存储状态.它们可以具有属性,但这些需要是抽象的或 ...

  9. SUSE Linux Enterprise Server设置IP地址、网关、DNS(转载)

      说明: ip:192.168.21.172 子网掩码:255.255.255.0 网关:192.168.21.2 dns:8.8.8.8 8.8.4.4 1.设置ip地址vi /etc/sysco ...

  10. CentOS6下源码安装mysql-5.6.25

    1.1.系统环境检查 1)检查系统版本 mkdir -p /server/tools/ cd /server/tools/ cat /etc/redhat-release 2)配置域名解析 vim / ...