今日内容:
如何查看对象的名称空间及对象名
继承的另一种使用
单继承与多继承
经典类与新式类
mro列表
菱形继承
接口
抽象类
鸭子类型
1、查看名称空间包含的变量:
使用类或对象名.__dict__查看
实际上在我们调用函数时就是在访问名称空间
比如Student.name实际上就是在调用 Student.__dict__["name"]
2、在使用类实例化对象时,代码的执行顺序为:
首先调用类产生一个空的对象
执行类的__init__方法,为对象添加自己独特的属性
#python为类内置的特殊属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)
class Human:
def __init__(self,name):
self.name = name def run(self):
print("%s is running..."%self.name) p1 = Human("lee")
p1.run() print(p1.__class__) # <class '__main__.Human'>
print(p1.__name__) # error:'Human' object has no attribute '__name__'
print(p1.__dict__) # {'name': 'lee'} --> 只展示对象自己的名称空间, print(Human.__dict__) # {'__module__': '__main__', '__init__': <function Human.__init__ at 0x000001E64CEC52F0>, 'run': <function Human.run at 0x000001E64CEC5378>, '__dict__': <attribute '__dict__' of 'Human' objects>, '__weakref__': <attribute '__weakref__' of 'Human' objects>, '__doc__': None}
print(Human.__class__) # <class 'type'>
print(Human.__name__) # 类的名字 p1 = Human("lee")
p2 = Human("lee")
p3 = Human("lee")
print(p1.run) # <bound method Human.run of <__main__.Human object at 0x000001A209BBE710>>
print(p2.run) # <bound method Human.run of <__main__.Human object at 0x000001A209BBE828>>
print(p3.run) # <bound method Human.run of <__main__.Human object at 0x000001A209BBEF60>>
print(p1) # <__main__.Human object at 0x000001C1B0B5D7B8>
print(p2) # <__main__.Human object at 0x000001C1B0B5D710>
print(p3) # <__main__.Human object at 0x000001C1B0B5D828>
1、继承的另一种使用:
在昨天的课程中讲了继承自己写的类,除了可以继承自己写的类,还可以继承系统已有的类
练习:
class MyList(list): def __init__(self,ele_name):
super().__init__(self)
self.ele_name = ele_name def append(self, object):
if object.__class__ == self.ele_name:
# print(object.__class__)
super().append(object)
else:
print("%s不是%s类型"%(object,self.ele_name.__name__)) li = MyList(int) li.append("")
li.append(123)
li.append(11) print(li) print(int(10).__class__)
2、单继承与多继承
单继承:子类只继承自一个父类,在进行属性查找时,首先查找自己的名称空间,在根据继承顺序依次进行查找
多继承:在python中,子类除了可以继承一个父类外,还可以继承多个父类,在进行属性查找时不能单独的依靠肉眼判断查找顺序,此时只能依靠mro列表判断查找顺序
查看继承:
在存在继承关系时,可以使用__base__()查看子类的第一个父类
可以使用__bases__()查看子类的全部父类,会产生一个元组
例子:

class C:
pass class B(C):
pass class MyList(list,B): def __init__(self,ele_name):
super().__init__(self)
self.ele_name = ele_name def append(self, object):
if object.__class__ == self.ele_name:
# print(object.__class__)
super().append(object)
else:
print("%s不是%s类型"%(object,self.ele_name.__name__)) print(MyList.__base__) # <class 'list'>
print(MyList.__bases__) # (<class 'list'>, <class '__main__.B'>)
3、经典类与新式类
经典类与新式类的分别只有在py2中才会体现,在py3中所有的类都是新式类
经典类:在python2中,当一个类没有父类,又没有显性的显示继承自object类,那么这个类就是经典类(老式类)
新式类:在python2中,当一个类显性的显示它继承自object类,那么他就是新式类
在python3中,所有的类,如果没有显示他们有父类,那他们就会隐形的继承自object类,所以,在python3中,所有的类都是新式类
换句话说就是:所有没有直接或间接继承自object的类都是经典类,所有直接或间接继承自object的类就会新式类
4、super()方法与mro列表
在单继承中,我们会使用super()来继承父类的某个方法,但是在多继承中,存在继承顺序的问题,那么super()到底继承自谁就会有异议
下方的例子我们经过分析,判断可能会报错,因为C的父类是object类,但是运行时没有报错,这与我们的分析时不同的
这是因为在多继承中会使用到mro列表,在进行属性查找时会根据mro列表进行继承
查看mro列表使用的是:当前类名.mro()
# 举例:

class B:
def test(self):
print("B test") class C:
def test(self):
print("C test")
super().test() class A(C,B):
# def test(self):
# print("A test")
pass a = A()
a.test()
print(A.mro()) # [<class '__main__.A'>, <class '__main__.C'>, <class '__main__.B'>, <class 'object'>]
5、菱形继承
类型继承就是当前类具有多个父类,而这些父类有具有相同的父类,那么这种继承关系就叫做菱形继承
菱形继承中属性的查找依赖于mro列表的顺序进行查找
# 例子:
class I:
def test(self):
print("I test") class K:
pass class E:
pass class F:
pass class G:
pass class H:
pass class D(H, I):
pass class C(F, H):
pass class B(E,F,G):
pass class A(B,C,D):
pass a = A()
a.test()
print(A.mro()) # I test
# [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>,
# <class '__main__.C'>, <class '__main__.F'>, <class '__main__.G'>,
# <class '__main__.D'>, <class '__main__.H'>, <class '__main__.I'>,
# <class 'object'>]

菱形继承

6、抽象与接口
接口:接口实际上就是一种规范制度,接口类中的方法不能拥有方法体,只是将方法罗列出来,作为模板供借鉴,这样可以更好的提高其扩展性
例如:我们平时使用电脑上的USB接口,如果我们要使用这个接口,就需要遵守这个接口的规范,如果不遵守,就不能使用这个接口
在python中,我们会使用接口类创建一个模板类,所有想要使用这个接口的类都要继承并重写模板类中的方法或者是按照接口方法的格式自己重新编写
# 我们也可以不使用模板类,这时候只要是按照模板类的格式自己定义方法也是可以使用接口的
# 举例:
# 接口类
class USB:
def read(self):
pass def write(self):
pass # 依据接口类的具体设备类
class Key(USB):
def read(self):
print("reading...") def write(self):
print("writing...") # 提供接口的类,只要依据接口的格式进行定义就能够被PC使用,不依据这个接口就不能被PC使用
class PC:
def connect_device(self,device):
device.read()
device.write()
7、抽象类
上例中,我们如果想要可以被PC类使用,就需要遵守接口,按照接口的方法进行类的创建
但是,有时为了避免遗忘接口有哪些方法,我们会将接口类定义为抽象类,这样,如果遵循其模板,就会报错
抽象类:具有抽象方法的类就是抽象类,只要一个方法中包含抽象方法,那么他就是抽象类
抽象类不能实例化,必须要有一个类继承抽象类,这个子类才可以进行实例化
抽象方法:没有函数体的方法,并且被@abc.abstractmethod 装饰器进行装饰的方法
下例中:
say_hi()方法没有函数体,且被@abc.abstractmethod 装饰器进行装饰,那么这个方法就是抽象方法
Test中包含有抽象方法,那么这个类就是抽象类 接口类与抽象类的区别:
接口类中的方法都不能具有函数体,抽象类中可以有方法具有函数体
接口类可以实例化对象,抽象类不能实例化对象
接口类可以不进行定义,只要按照接口类的模板进行类的定义即可
抽象类也可以不进行定义
# 举例:

import abc

class Test(metaclass=abc.ABCMeta):

    @abc.abstractmethod
def say_hi(self):
pass class TT(Test): def say_hi(self):
print("i am TT obj") t = TT()
t.say_hi()
# 鸭子类型

说如果一个对象叫声像鸭子,走路像鸭子,长得像鸭子,那它就是鸭子 

是python 推荐的方式,python不喜欢强行限制你 
class PC():

    def conntent_device(self, usb_device):
usb_device.open()
usb_device.work()
usb_device.close() class Mouse:
# 实现接口规定的所有功能
def open(self):
print("mouse opened") def work(self):
print("mouse working...") def close(self):
print("mouse closed") mouse = Mouse()
pc = PC() pc.conntent_device(mouse) class KeyBoard:
def open(self):
print("KeyBoard opened") def work(self):
print("KeyBoard working...") def close(self):
print("KeyBoard closed") key1 = KeyBoard() # 如果key1的特征和行为都像USB设备 那就把它当做USB设备来使用
# 对于使用者而言可以不用关心这个对象是什么类,是如如何是实现,
pc.conntent_device(key1)

day25 多继承、接口、抽象类、鸭子类型的更多相关文章

  1. java 接口 继承 接口 抽象类 继承 实体类

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 接口 可以 继承 接口 抽象类 可以 实现 接口 抽象类 继承实体类 需要 实体类 有 ...

  2. 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

    接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)? 答:接口可以继承接口.抽象类可以实现(implements)接口,抽象类 ...

  3. day25 面向对象之多态和鸭子类型

    1.封装方法 如何封装:给方法名称前面加上双下划线 # ATM 的取款功能 # 1.插入银行卡 2.输入密码 3.选择取款金额 4.取款 class ATM: def __insert_card(se ...

  4. python基础语法17 面向对象4 多态,抽象类,鸭子类型,绑定方法classmethod与staticmethod,isinstance与issubclass,反射

    多态 1.什么是多态? 多态指的是同一种类型的事物,不同的形态. 2.多态的目的: “多态” 也称之为 “多态性”,目的是为了 在不知道对象具体类型的情况下,统一对象调用方法的规范(比如:名字). 多 ...

  5. 【Java面试题】60 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)? 抽象类中是否可以有静态的main方法?

    接口可以继承接口.抽象类可以实现(implements)接口,抽象类可以继承具体类.抽象类中可以有静态的main方法. 问:  抽象类是否可继承实体类 (concrete class) 答: 抽象类是 ...

  6. kotlin 类 接口 抽象类 子类类型有限的class 。sealed class

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 用 private 封装,可以防止别人修改. 就好像 内有高压,危险,不让碰.

  7. 接口的定义——默认加public abstract默认全局常量;与继承不同,子类可以同时实现多个接口;抽象类实现接口;接口继承接口

    一. 接口的定义 接口中定义的方法,全部都为抽象方法,默认加public abstract 接口中定义的变量,全部为全局常量,默认加public static final 二.与继承不同,子类可以同时 ...

  8. day25 面向对象继承,多态,

    这两天所学的都是面向对象,后面还有几天也是它,面向对象主要有三个大的模块,封装,继承,多态,(组合),昨天主要讲了面向对象的命名空间,还有组合的用法,今天是讲的继承还有继承里面所包括的钻石继承,以及多 ...

  9. python与鸭子类型

    部分参考来源:作者:JasonDing  https://www.jianshu.com/p/650485b78d11##s1 首先介绍下面向对象(OOP)的三大特征: (1)面向对象程序设计有三大特 ...

随机推荐

  1. Markdown使用教程(转载收藏)

    基础语法 标题 Markdown支持6种级别的标题,对应html标签 h1 ~ h6 # h1 ## h2 ### h3 #### h4 ##### h5 ###### h6 以上标记效果如下: h1 ...

  2. CodeForces - 837E - Vasya's Function | Educational Codeforces Round 26

    /* CodeForces - 837E - Vasya's Function [ 数论 ] | Educational Codeforces Round 26 题意: f(a, 0) = 0; f( ...

  3. cookie与session的区别?

    一.cookie机制和session机制的区别 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案.同时我们也看到,由于才服务器端保持状态的方 ...

  4. Linux之GDB命令(二)

    gdb命令: 前提条件:可执行文件必须包含调试信息 gcc -g gdb 文件名 –启动gdb调试 查看代码命令   当前文件:     list 行号(函数名)   指定文件:     list 文 ...

  5. 数据结构实验之链表四:有序链表的归并(SDUT 2119)

    #include <bits/stdc++.h> using namespace std; struct node { int data; struct node *next; }; st ...

  6. C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)

    [1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...

  7. php-m 与 phpinfo 不一致的解决办法

    1.查看PHP当前加载的php.ini文件地址,在控制台输入以下命令: 1 php -i | grep php.ini 2.控制台返回的信息 1 2 Configuration File (php.i ...

  8. CodeForces 755D PolandBall and Polygon ——(xjbg)

    每次连线,起点和终点之间,每一个被点亮的点,这些点都能连出去两条线,因此可以增加的块数+2(1这个点除外,因为只有连出的点没有连进的点),计算起点和终点之间有几个点被点亮即可,然后1这个点特判一下.感 ...

  9. 【CF671D】 Roads in Yusland(对偶问题,左偏树)

    传送门 洛谷翻译 CodeForces Solution emmm,先引入一个对偶问题的概念 \(max(c^Tx|Ax \leq b)=min(b^Ty|A^Ty \ge c)\) 考虑这个式子的现 ...

  10. elasticsearch-head后台运行

    运行插件 # npm run start > elasticsearch-head@0.0.0 start /usr/local/elasticsearch-head-master > g ...