python abc模块

来源:互联网 发布:javascript视教程下载 编辑:程序博客网 时间:2024/06/06 00:30

面向对象的设计中,抽象类,接口这些必不可少的东西,在python中是如何体现的呢?

python作为一个动态语言,没有强类型的检查,而是以鸭子类型的方式提现,在执行的时候python不严格要求你必须是继承指定的父类而来,只要在调用的时候你有相应的方法和属性就可以了,长的像鸭子你就是鸭子。

也正是基于python这样的特性,python中没有interface的概念,有说interface并不是普遍存在的,而是作为一个特例出现在java中,为的是解决多继承的问题。python支持多继承,自然没有这个需要了。然而我们难免会有这样的需求:子类必须实现某些指定的方法和属性,否则就抛异常。使用一些笨方法自然是可以达到相同的效果,但是python为我们提供了abc模块。

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中的abc模块是如何玩儿的:
python-3.6.0-docs-html/library/abc.html?highlight=abc#module-abc
https://www.python.org/dev/peps/pep-3119/

from abc import ABCMeta, abstractmethod, abstractpropertyclass Drawable(metaclass=ABCMeta):    """docstring for Drawable"""    @abstractproperty    def size(self):        # return 'mysize'        pass    @abstractmethod    def draw(self, x, y, scale=1.0):        # print(x * scale, y * scale)        pass    def double_draw(self, x, y):        self.draw(x, y, scale=2.0)class Cicle(Drawable):    # 1. 使用继承的方法    """docstring for Cicle"""    def draw(self, x, y, scale=1.0):        print(x * scale, y * scale)    @property    def size(self):        return 'Cicle size'# Cicle如果没有override draw函数和size 属性,那么实例化的时候就会报错# TypeError: Can't instantiate abstract class Cicle with abstract methods draw, sizec = Cicle()print(dir(c))c.draw(1, 2)c.double_draw(1, 2)print(isinstance(c, Drawable))  # Trueprint(isinstance(c, Drawable))  # Trueclass Rectangle():    """docstring for Cicle"""    pass# 使用抽象类函数的register方法注册具体的class# 通过注册的类,可以直接实例化,但是无法访问抽象类的所有成员# 其实就是只是让isinstance、issubclass识别注册的类为抽象类的成员和实例Drawable.register(Rectangle)r = Rectangle()# r.double_draw(1, 2) # AttributeError: 'Rectangle' object has no attribute 'double_draw'print(dir(r))print(isinstance(r, Drawable))  # Trueprint(issubclass(Rectangle, Drawable))  # True# ['__abstractmethods__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', '_abc_registry', 'double_draw', 'draw', 'size']# 1.0 2.0# 2.0 4.0# True# True# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']# True# True# [Finished in 0.2s]
原创粉丝点击