免费推广网站入口202,快速开发网站的应用程序,怎么制作糖葫芦教程,如何提升网站的排名Python的鸭子特性#xff08;duck typing#xff09;
Python中自定义的类只要实现了某种特殊的协议#xff0c;就能赋予那种行为#xff0c;举一个简单的例子#xff1a; class A:def __len__(self):return 0
a A()
print(len(a)) 如上所示#xff0c;自己定义了一个类… Python的鸭子特性duck typing
Python中自定义的类只要实现了某种特殊的协议就能赋予那种行为举一个简单的例子 class A:def __len__(self):return 0
a A()
print(len(a)) 如上所示自己定义了一个类实现了__len__的魔法方法就可以使用内置函数len()获取对象长度。如果实现了__getitem__魔法方法自定义对象就能称为”序列类型”可以使用类似list序列那样的操作比如a[1]获取第2个元素......
Python的白鹅特性抽象基类
在Java中有interface接口的概念而在Python中没有这个概念取而代之的是抽象基类。在Python中定义一个抽象基类如下 import abc
class Base(abc.ABC):abc.abstractmethoddef func(self):doc 只需要实现func的接口即可 class MyClass(Base):def func(self):passPython虚拟子类使用__subclasshook__
Python原生定义了抽象基类Sized里面实现了__len__方法我们可以自定义类来继承Sized实现里面的__len__方法Sized源码如下 class Sized(metaclassABCMeta):__slots__ ()abstractmethoddef __len__(self):return 0classmethoddef __subclasshook__(cls, C):if cls is Sized:return _check_methods(C, __len__)return NotImplemented 如上所示我们看到了它实现了__subclasshook__方法检查子类和子类的mro上所有的类是否有__len__方法如果没有返回NotImplemented。当然我们不必继承Sized而是使用虚拟子类virtual subclass技术只实现__len__协议隐式继承了Sized。
下面我们仿造Sized自定义一个抽象基类 import abc
class Base(abc.ABC):abc.abstractmethoddef my_protocol(self):自定义协议classmethoddef __subclasshook__(cls, subclass):if cls is Base:if any(my_protocol in B.__dict__ for B in subclass.__mro__):return Truereturn NotImplemented 接下来我们定义一个子类隐式继承Base #并没有显式继承Base
class MyClass:def my_protocol(self):pass
if __name__ __main__:k MyClass()print(isinstance(k, Base)) #Trueprint(issubclass(MyClass, Base))#Trueprint(Base._abc_impl) 如上所示我们只需要实现my_protocol协议就会隐式继承自抽象基类这样就实现了虚拟子类的创建。