类型检查
创建类的实例时,该实例的类型为类本身:
class Foo(object):
pass f = Foo()
要测试实例是否属于某个类,可以使用type()内置函数:
>>> type(f) == Foo
True
当然,python中不建议如此检查,更好的办法是使用内置类型检查函数isinstance(obj, cls):
>>> isinstance(f, Foo)
True
同样的,内置函数issubclass(cls1, cls2)可以用做子类的检查:
class SubFoo(Foo):
pass >>> issubclass(SubFoo, Foo)
True
这两个内置函数的第二个参数可以是一个单独的类,也可以是几个类的元组:
>>> isinstance(1, (str, int))
True
以下两个特殊方法可用于重新定义这两个内置函数:
__instancecheck__(cls, obj)
__subclasscheck__(cls, subcls)
鸭子类型
python是门动态语言,调用对象的时候是不用考虑对象的类型的,而只需要对象有某些特定的属性或者行为即可,也就是鸭子类型。
为了保持程序的松散耦合,我们可以不用继承,而只是模仿一些对象的行为:
class File(object):
def open(self):
print 'open File' class FileLike(object):
def open(self):
print 'open FileLike' def foo(f):
f.open()
只要定义了open()方法的实例,就可以作为函数foo()的参数:
>>> f = File()
>>> fl = FileLike()
>>> foo(f)
open File
>>> foo(fl)
open FileLike
当我们测试对象是否可以作为foo()的参数时,要同时进行两次isinstance()类型检查,如果类型更多的话呢?
现在我们可以将File和FileLike分组并对其进行一次类型检查:
class FileLikeClass(object):
def __init__(self):
self.reg = set() def register(self, cls):
self.reg.add(cls) def __instancecheck__(self, obj):
return self.__subclasscheck__(type(obj)) def __subclasscheck__(self, subcls):
return any(cls in self.reg for cls in subcls.mro()) flc = FileLikeClass()
flc.register(File)
flc.register(FileLike)
上述代码使用FileLikeClass创造一个对象,将要检查的类型放入对象的一个集合属性中,然后重新定义__instancecheck__(cls, obj)与__subclasscheck__(cls, subcls)方法,
进行子类检查时,会检查子类及子类的基类是否在集合中,进行类型检查时,会检查对象的类型是否是集合中的类的子类:
>>> f = File()
>>> isinstance(f, flc)
True
>>> fl = FileLike()
>>> isinstance(fl, flc)
True
当然,python提供了一种更正式的机制来分组对象,定义接口并进行类型检查----抽象基类
抽象基类
要定义抽象基类,需要使用abc模块,该模块定义一个元类(ABCMeta)和两个装饰器(@abstractmethod,抽象方法)与(@abstractproperty, 抽象特性),使用方法如下:
from abc import ABCMeta, abstractmethod, abstractproperty class AbsFile(object):
__metaclass__ = ABCMeta @abstractmethod
def open(self):
pass
抽象基类就是定义各种方法而不做具体实现的类,抽象基类是无法实例化的:
>>> AbsFile()
TypeError: Can't instantiate abstract class AbsFile with abstract methods open
任何继承自抽象基类的类也必须实现这些方法,否则无法实例化:
class File(AbsFile):
pass
实例化失败:
>>> File()
TypeError: Can't instantiate abstract class File with abstract methods open
需定义open方法:
class File(AbsFile):
def open(self):
print 'open File'
当然抽象基类中也可以对抽象方法进行具体实现,在子类中可以通过super()来调用:
class AbsFile(object):
__metaclass__ = ABCMeta @abstractmethod
def open(self):
print 'open AbsFile' class File(AbsFile):
def open(self):
super(File, self).open()
print 'open File'
实例化:
>>> File().open()
open AbsFile
open File
如果只想执行类型检查的话,可以使用register()方法:
from abc import ABCMeta, abstractmethod, abstractproperty class AbsFile(object):
__metaclass__ = ABCMeta @abstractmethod
def open(self):
pass class File(object):
pass AbsFile.register(File)
向抽象基类注册某个类时,是不会检查该类是否实现了抽象基类的抽象方法或者特性的,只会影响类型检查:
>>> f = File()
>>> isinstance(f, AbsFile)
True
python的collections模块定义了与序列,集合和字典有关的各种抽象基类,numbers模块定义了与数字有关的抽象基类。
Python中的对象行为与特殊方法(二)类型检查与抽象基类的更多相关文章
-
Python中的对象行为与特殊方法(一)对象的创建与销毁
Python中类调用__new__()类方法来创建实例,调用__init__()方法来初始化对象,对象的销毁则调用__del__()方法. __new__()方法第一个参数为类cls,通常返回cls的 ...
-
python中json对象转换出错解决方法
今天在使用python中的json转换碰到一个问题: 接收一个post的json字符串: s={"username":"admin","passwor ...
-
python中的json的基本使用方法
在python中使用json的时候,主要也就是使用json模块,json是以一种良好的格式来进行数据的交互,从而在很多时候,可以使用json数据格式作为程序之间的接口, #!/usr/bin/env ...
-
Python中os和shutil模块实用方法集…
Python中os和shutil模块实用方法集锦 类型:转载 时间:2014-05-13 这篇文章主要介绍了Python中os和shutil模块实用方法集锦,需要的朋友可以参考下 复制代码代码如下: ...
-
Python中os和shutil模块实用方法集锦
Python中os和shutil模块实用方法集锦 类型:转载 时间:2014-05-13 这篇文章主要介绍了Python中os和shutil模块实用方法集锦,需要的朋友可以参考下 复制代码代码如下: ...
-
python之抽象基类
抽象基类特点 1.不能够实例化 2.在这个基础的类中设定一些抽象的方法,所有继承这个抽象基类的类必须覆盖这个抽象基类里面的方法 思考 既然python中有鸭子类型,为什么还要使用抽象基类? 一是我们在 ...
-
Python抽象基类之声明协议
抽象基类之--声明协议 上回讲了Python中抽象基类的大概,相信大家对abcmeta以及什么是抽象基类已经有所了解.传送门 现在我们来讲讲抽象基类的另一个常用用法--声明协议 所谓声明协议,有点像J ...
-
Python中的str与unicode处理方法
Python中的str与unicode处理方法 2015/03/25 · 基础知识 · 3 评论· Python 分享到:42 原文出处: liuaiqi627 的博客 python2.x中处理 ...
-
python中拷贝对象的区别
一.赋值.引用 在python中赋值语句总是建立对象的引用值,而不是复制对象.因此,python变量更像是指针,而不是数据存储区域 这点和大多数语音类似吧,比如C++.Java等 1.先看个例子: v ...
随机推荐
-
如何在Mac系统里面更新 Ansible 的 Extra Modules
最近遇到一个问题 seport is not a legal parameter in an Ansible task or handler 原因是我本地 Ansible 的 Extra Module ...
-
java 获取特定天数的时间戳
public Timestamp strToDate(int type){ Timestamp time = null; DateFormat format2= new SimpleDateForma ...
-
Linux05--Shell程序设计01
1.Shell脚本介绍 基本介绍: shell脚本是一个可执行的纯文本文件,由多个shell命令组成. 命令的执行是从上而下,从左而右的分析和执行 命令,参数间的多个空白也会被忽略 #是注释 #!用于 ...
-
基于jquery 的分页插件,前端实现假分页效果
上次分享了一款jquery插件,现在依旧分享这个插件,不过上一次分享主要是用于regular框件,且每一页数据都是从后端获取过来的,这一次的分享主要是讲一次性获取完数据 然后手动进行分页.此需求基本上 ...
-
Minicom串口工具安装及配置
Minicom串口工具安装及配置 1. 简述 嵌入式开发多采用串口线连接电脑进行开发及调试. 2 安装及配置串口工具(以Minicom为例) Tiny4412开发板提供的有RS232电平的DB9公头接 ...
-
SSH网上商城---需求分析+表关系分析
SSH---小编初次接触的时候傻傻的以为这个跟SHE有什么关系呢?又是哪路明星歌手,后来才知道小编又土鳖了,原来SSH是这个样子滴,百度百科对她这样阐述,SSH即 Spring + Struts +H ...
-
最优的路线(floyd最小环)
问题描述 学校里面有N个景点.两个景点之间可能直接有道路相连,用Dist[I,J]表示它的长度:否则它们之间没有直接的道路相连.这里所说的道路是没有规定方向的,也就是说,如果从I到J有直接的道路,那么 ...
-
【SFA官方译文】:Spring Cloud Data Flow中的ETL
原创: 影宸风洛 SpringForAll社区 昨天 原文链接:https://www.baeldung.com/spring-cloud-data-flow-etl 作者:Norberto Ritz ...
-
hadoop之 node manager起不来, 执行mapreduce 程序hang住
现象: node manager起不来, 执行mapreduce 程序hang住 namenode 进程状态查询[root@hadp-master sbin]# jps8608 ResourceMan ...
-
(转)MyEclipse快捷键大全
-------------------------------------MyEclipse 快捷键1(CTRL)-------------------------------------Ctrl+1 ...