首页 > 代码库 > python 抽象类分析
python 抽象类分析
最近在看bottle.py源码,里面自定了多个类字典的类。这些类的定义继承了collections中多个抽象类。比如MutableMapping。
1、在讲抽象类之前,先说下抽象方法的实现。
抽象方法是基类中定义的方法,但却没有任何实现。在java中,可以把方法申明成一个接口。而在python中实现一个抽象方法的简单的方法是:
1
2
3
|
class Sheep(object):
def get_size(self):
raise NotImplementedError
|
任何从Sheep继承下来的子类必须实现get_size方法。否则就会产生一个错误。但这种实现方法有个缺点。定义的子类只有调用那个方法时才会抛错。这里有个简单方法可以在类被实例化后触发它。使用python提供的abc模块。
1
2
3
4
5
6
7
|
import abc
class Sheep(object):
__metaclass__ = abc.ABCMeta
@abc.absractmethod
def get_size(self):
return
|
这里实例化Sheep类或任意从其继承的子类(未实现get_size)时候都会抛出异常。
因此,通过定义抽象类,可以定义子类的共同method(强制其实现)。
2、抽象类的定义。
python中,抽象类通过abc模块实现。
1
2
3
4
5
6
7
8
9
10
11
12
|
import abcclass PluginBase(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def load(self, input):
"""Retrieve data from the input source and return an object."""
return
@abc.abstractmethod
def save(self, output, data):
"""Save the data object to the output."""
return
|
具体化抽象类,可以有两种方式,一种通过注册(register),另外一种通过继承。
注册方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import abc
from abc_base import PluginBase
class RegisteredImplementation(object):
def load(self, input):
return input.read()
def save(self, output, data):
return output.write(data)PluginBase.register(RegisteredImplementation)
if __name__ == ‘__main__‘:
print ‘Subclass:‘, issubclass(RegisteredImplementation, PluginBase)
print ‘Instance:‘, isinstance(RegisteredImplementation(), PluginBase)
|
继承方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import abc
from abc_base import PluginBase
class SubclassImplementation(PluginBase):
def load(self, input):
return input.read()
def save(self, output, data):
return output.write(data)
if __name__ == ‘__main__‘:
print ‘Subclass:‘, issubclass(SubclassImplementation, PluginBase)
print ‘Instance:‘, isinstance(SubclassImplementation(), PluginBase)
|
执行发现,注册方式和继承方式不同在于,注册方式,当没有实现抽象方法时,实例化时候不会报错,但调用时候会报错。
3、抽象类中除了抽象方法外,也可以实现抽象属性(@abstraproperty)。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import abcclass Base(object):
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def value(self):
return ‘Should never get here‘class Implementation(Base):
@property
def value(self):
return ‘concrete property‘try:
b = Base()
print ‘Base.value:‘, b.valueexcept Exception, err:
print ‘ERROR:‘, str(err)i = Implementation()print ‘Implementation.value:‘, i.value
|
另外子类中抽象属性实现必须与抽象属性定义一致。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import abc
class Base(object):
__metaclass__ = abc.ABCMeta
def value_getter(self):
return ‘Should never see this‘
def value_setter(self, newvalue):
return
value = abc.abstractproperty(value_getter, value_setter)
class PartialImplementation(Base):
@abc.abstractproperty
def value(self):
return ‘Read-only‘class Implementation(Base):
_value = ‘Default value‘
def value_getter(self):
return self._value
def value_setter(self, newvalue):
self._value = newvalue
value = property(value_getter, value_setter)try:
b = Base()
print ‘Base.value:‘, b.valueexcept Exception, err:
print ‘ERROR:‘, str(err)try:
p = PartialImplementation()
print ‘PartialImplementation.value:‘, p.valueexcept Exception, err:
print ‘ERROR:‘, str(err)i = Implementation()
print ‘Implementation.value:‘, i.valuei.value = ‘New value‘print ‘Changed value:‘, i.value
|
4、collections
collections模块定义了几个抽象类。
General container classes:
-
Container
-
Sized
Iterator and Sequence classes:
-
Iterable
-
Iterator
-
Sequence
-
MutableSequence
Unique values:
-
Hashable
-
Set
-
MutableSet
Mappings:
-
Mapping
-
MutableMapping
-
MappingView
-
KeysView
-
ItemsView
-
ValuesView
Miscelaneous:
-
Callable
python的内置类型在import collections时,会自动被注册到这些类中。因此你可以安全的使用isinstance或issubclass来保证执行某些api
python 抽象类分析