python的接口和抽象类
抽象基类
有些面向对象的语言,如JAVA,支持接口,可以声明一个支持给定的一些方法方法,或者支持给定存取协议的类。抽象基类(或者ABCs)是Python里一个相同的特性。抽象基类由abc模块构成,包含了一个叫做ABCMeta的metaclass。这个metaclass由内置的isinstance()和issubclass()特别处理,并包含一批会被Python开发人员广泛用到的基础抽象基类。将来的Python版本可能会加入更多的抽象基类。
比如说有某个特定类你想知道它是否支持dictionary类型的存取。然而dictionary类型是个模糊的表述。它可能意味着可以通过obj[1]进行存取。那是否也意味着obj[2]= value这种赋值也起作用呢?又或者该对象将具备keys(), values()和items()方法?迭代的变种如iterkeys(),copy()和update()又如何呢?通过对象迭代的iter()呢?
Python 2.6的collections模块包括了许多不同的抽象基类来表示出这些不同。Iterable表明一个类定义了__iter__(),Container意味着该类定义了__contains__()方法,因此支持x in y表达式。基本的dictionary接口包括存取数据和keys(),values(),以及items(),由MutableMapping抽象基类定义。
你可以让你的类继承某个特定的抽象基类,来表示它们支持抽象基类接口:
import collections
class Storage(collections.MutableMapping):
...
另外,你可以不继承基类,以调用抽象基类的register()方法的方式注册该类。
import collections
class Storage:
...
collections.MutableMapping.register(Storage)
相对于你写的类来说,从抽象基类继承可能更清晰。当你已经写了一个新的抽象基类,能描述一个存在的类型或类,或者你想声明某些第三方类实现了一个抽象基类,
register()方法是有用的。例如,如果你定义了一个PrintableType抽象基类,以下是合法的:
# Register Python's types
PrintableType.register(int)
PrintableType.register(float)
PrintableType.register(str)
类应当遵循由抽象基类指明的语义,但是Python不能检查这一点;类作者应该理解抽象基类的需求,并据此实现代码。
要检查一个对象是否支持某个特定接口,你可以这样写:
def func(d):
if not isinstance(d, collections.MutableMapping):
raise ValueError("Mapping object expected, not %r" % d)
不要认为你必须像上面的例子那样,写许多检查性的代码。Python有很强的duck-typing传统,从来不会进行显式的类型检查。代码只是简单的调用对象的方法,认为这些方
法会存在,如果不存在就会抛出异常。抽象基类检查时一定要谨慎,最好在非常必要的时候才那样做。
你可以在类的定义中用abc.ABCMeta作为metaclass写自己的抽象基类:
from abc import ABCMeta, abstractmethod
class Drawable():
__metaclass__ = ABCMeta
@abstractmethod
def draw(self, x, y, scale=1.0):
pass
def draw_doubled(self, x, y):
self.draw(x, y, scale=2.0)
class Square(Drawable):
def draw(self, x, y, scale):
...
在以上的Drawable抽象基类中,draw_doubled()方法会按对象两倍的大小画出来,并且可以调用Drawable自己的方法来实现。因此实现这个抽象基类的类不需要
提供它们自己的draw_doubled()实现,尽管他们可以那样做。然而draw()的实现是必须的;抽象基类不能提供一个有用的一般实现。
你可以在必须实现的方法,如draw()中应用@abstractmethod修饰符;Python会对那些没有定义该方法的类抛出异常。注意,只有当你试图创建一个子类实例,但是却缺少该方法的时候才会抛出异常。
>>>class Circle(Drawable):
... pass
...
>>>c=Circle()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Circle with abstract methods draw
>>>
抽象数据属性可以用@abstractproperty decorator声明:
from abc import abstractproperty
...
@abstractproperty
def readonly(self):
return self._x
子类必须定义一个readonly()属性。
===================================
http://bbs.chinaunix.net/thread-771123-1-1.html
java中的抽象类是为了实现c++中的抽象类和模板之类的东西
接口是为了解决java不能多继承的问题
很显然楼主是从java才开始接触面向对象程序设计的。实际上java的“接口”是一个特例而非普通现象。如果可以多继承的话,那还要接口干什么?
实际上python才是最符合现实逻辑的“面向对象”
python允许多继承,正如现实中,你既是公民也是纳税人,我们直接使用这些“类”而不需要特别的创建什么“纳税人接口”
python中所有的类,都是抽象类,或者说根本不存在抽象类,类方法可以直接使用,“类”本身在定义的时候就已经实例化,你可以通过输入:某类[回车]看到其内存句柄。这是符合事实的,并且时简约明了的。
而在C++和java当中,一个类定义了以后,肯定是占用了内存空间,但是同时他又没有实例化,如果要使用的话还得实例化一次,又要占用一些内存空间。而类定义所占用的内存空间,使用率很低。
python中不存在“基类”的概念,也没有单根,更没有基本类型,所有的一切都是对象。
python是无神论的最完美体现,没有亚当,没有上帝,没有鬼神,没有唯一的主。你爱信什么信什么,爱是什么是什么,没有任何约束,但是不能存在特殊。
另外,python根本没有意义去模仿java的接口,因为那完全没必要,python的标准类就完全包含java中的接口的所有功能。倒是模仿一下c++的模板会有些实际用途。
====================================
python接口的例子
http://pypi.python.org/pypi/zope.interface
twisted的twisted\internet\interface.py里使用zope.interface
python的接口和抽象类的更多相关文章
- python之接口与抽象类
一.接口与归一化设计 1.什么是接口 1)是一组功能集合 2)接口的功能是用于交互 3)接口只定义函数,但不涉及函数的实现 4)这些功能是相关的 2.为什么要用接口 接口提取了一群类共同的函数,然后让 ...
- 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装
抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...
- Python开发基础-Day18继承派生、组合、接口和抽象类
类的继承与派生 经典类和新式类 在python3中,所有类默认继承object,但凡是继承了object类的子类,以及该子类的子类,都称为新式类(在python3中所有的类都是新式类) 没有继承obj ...
- python面向对象编程 继承 组合 接口和抽象类
1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均用点来访问自己的 ...
- python开发面向对象基础:接口类&抽象类&多态&钻石继承
一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实 ...
- Py修行路 python基础 (十五)面向对象编程 继承 组合 接口和抽象类
一.前提回忆: 1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均 ...
- python基础之继承派生、组合、接口和抽象类
类的继承与派生 经典类和新式类 在python3中,所有类默认继承object,但凡是继承了object类的子类,以及该子类的子类,都称为新式类(在python3中所有的类都是新式类) 没有继承obj ...
- python笔记5 接口类抽象类 封装 反射 设计模式 模块 :random随机数 josn shelve持久化存储
接口类抽象类 接口类:接口类就是制定一个规则,让其他人按照我的规则去写程序. #!/usr/bin/env python from abc import ABCMeta,abstractmethod ...
- day 25 面向对象之接口、抽象类、多态、异常处理、反射、断言
复习 '''继承1.父类:在类后()中写父类们class A:passclass B:passclass C(A, B):pass2.属性查找顺序:自己 -> ()左侧的父类 -> 依 ...
随机推荐
- 快速排查SQL服务器阻塞语句
SELECT*FROM sys.sysprocesses and blocked> --可以查看阻塞 SELECT SPID=p.spid, DBName =convert(CHAR(),d.n ...
- 妙味远程课堂-JS热身运动-上
希望某个元素移除视线 display:none//显示无 visibility:hidden//可见性 隐藏 width/height 改为0 透明度 定位,left/top值为负值 用与背景颜色一样 ...
- linux环境安装nagiosgraph将nagios的性能数据绘制成动态图表?
需求描述: 在安装完成nagios之后,比如有监控磁盘负载信息的,连接数的,进程数的,可以通过安装nagiosgraph软件, 将nagios的性能数据绘制成图表,可以看到一段时间内数据的变化 环境说 ...
- mysql中查看数据库的版本,什么版本
需求:查看当前使用的数据库是哪个版本的,什么版本 select version(); 查询结果: 备注:通过version()函数查询出来当前使用的数据库版本是5.5.57-log 文档创建时间:20 ...
- Go语言的类型转换和类型断言
https://my.oschina.net/chai2010/blog/161418 https://studygolang.com/articles/9335 类型转换.类型断言和类型切换 ht ...
- node.js--Less
摘要: 现在已经有许多站点使用Node.js,所以在Node.js上配置Less环境也是很重要的,下面分享下如何在Node上使用Less开发,前提是你电脑上已经安装node. 安装: 只需要执行下面一 ...
- 树莓派(Raspberry Pi)USB无线网卡自动连接,二代B
Raspberry Pi 使用USB无线网卡的时候不会因为路由重启而掉线. #!/bin/bash while true ; do if ifconfig wlan0 | grep -q " ...
- MyBatis入门程序之mapper映射文件常用配置命令
1.ResultMap高级结果映射 如果查询出的列名和属性名不一致,可以通过ResultMap做映射,放在statement的输出类型中 如下: 2.动态SQL,使用各种动态标签实现动态拼接sql,常 ...
- CentOS7上Mongodb安装、卸载
参考官网https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/ 一.安装 1.配置yum管理包 1).在路径/etc/ ...
- linux-nohup后台运行
先说一下linux重定向: 0.1和2分别表示标准输入.标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出. 在一般使用时,默认的是标准输出,既1.当我们需要特殊用途时,可以使用其他标 ...