python:抽象类和接口

起因

最近在写上两篇restframework的博文中遇到了一个问题,认证和权限中有一个方法定义必须为固定方法名,不是的话就报错,我当时并不知道是为什么,以为是某种特性,也没有深究,今天在群里和别人聊天的时候,突然看到其他人也有这个问题,然后一查资料,发现了这确实是一个有点意思的东西。

java中的抽象类和接口

参数抽象类接口
默认的方法实现它可以有默认的方法实现接口完全是抽象的。它根本不存在方法的实现
实现子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
构造器抽象类可以有构造器接口不能有构造器
与正常Java类的区别除了你不能实例化抽象类之外,它和普通Java类没有任何区别接口是完全不同的类型
访问修饰符抽象方法可以有public、protected和default这些修饰符接口方法默认修饰符是public。你不可以使用其它修饰符。
main方法抽象方法可以有main方法并且我们可以运行它接口没有main方法,因此我们不能运行它。
多继承抽象方法可以继承一个类和实现多个接口接口只可以继承一个或多个其它接口
速度它比接口速度要快接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
添加新方法如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。如果你往接口中添加方法,那么你必须改变实现该接口的类。

用python伪代码模拟接口和模型类

接口

	Interface IMessage:
	def func1(self):
		pass 
	def func2(self):
		pass 

class Msg(IMessage):
	def func1(self):
		print('func1') 
	def func2(self):
		print('func1') 

上面需要说明的是,假如这是一个接口,它可以内部定义方法,但方法里不能有值,只能写pass,而如果有多个函数,那么它也必须全部是pass,否则就会报错

下面我们可以定义一个类去继承这个接口,那么我们定义的这个类就可以定义参数以及做其它操作,但函数的名字、个数必须和接口中的方法相同,否则约束还是不成立,依然报错。这是一种约束


抽象类

class abstract IMessage:
	def abstract func1(self):
		pass 
	def abstract func2(self):
		pass 
	
	def func3(self):
		print('123') 
		
class Msg(IMessage):
	def func1(self):
		print('func1') 
	def func2(self):
		print('func1') 

在抽象类里面,可以有抽象方法和非抽象方法,抽象方法为pass,非抽象方法就是普通的函数。那么当另一个类来继承这个抽象类时,当前的msg类方法,要全部继承imassage中的抽象方法,但非抽象方法可写可不写,这是一种约束加继承。

python中的抽象类/抽象方法

from abc import ABCMeta,abstractmethod
class Abstract(metaclass=ABCMeta):	# 抽象类
    @abstractmethod
    def func(self):
        pass	# 指定了某种规范

class A(Abstract):
    def func(self):	 # 遵守这种规范
        print("A")

class B(Abstract):
    pass

a = A()
b = B()#报错,没有实现抽象方法

在定义抽象类前需要从类库abc导入ABCmeta类(即Metaclass for defining Abstract BaseClasses,抽象基类的元类)和abstractmethod类。
python中是没有接口的,但是有抽象方法和抽象类,通过abc这个模块,另外就是当我们定义了一个这样的方法时,相当于制定了规则,那么后来者需要这个规则,否则将会抛异常。

restframework中的约束类

在我们上两篇博文中,我们再自定义认证函数时,都重写了

class BaseAuthentication(object):
    """
    All authentication classes should extend BaseAuthentication.
    """

    def authenticate(self, request):
        """
        Authenticate the request and return a two-tuple of (user, token).
        """
        raise NotImplementedError(".authenticate() must be overridden.")

也就是因为这个原因,所以我们后面继承的自定义认证类需要去继承这个authenticate方法,否则就会报错,报错信息为NotImplementedError,一般基本所有的语言如果没有去继承这个约束类中的约束方法,都会报这个错,但python中的是抛异常而已。我们再来看看我们当初写的认证类:

from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication

from .models import Token
class TokenAuth(BaseAuthentication):
    def authenticate(self,request):
        token = request.GET.get("token")
        token_obj = Token.objects.filter(token=token).first()
        if not token_obj:
            raise exceptions.AuthenticationFailed("验证失败123!")
        else:
            return token_obj.user.name,token_obj.token

关于这个类的解释在认证.中有说明。另外权限也差不多的意思,这里就不再提了。



参考文献:

  1. https://pypi.org/project/zope.interface/
  2. http://www.importnew.com/12399.html
  3. https://blog.csdn.net/fenglibing/article/details/2745123
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
抽象类接口都是面向对象编程中的概念,用于描述一种类型或者类的行为。在 Python 中,抽象类接口的实现方式有所不同。 抽象类是一个包含抽象方法的类,抽象方法是一种没有具体实现的方法,只有方法名和参数列表,没有函数体。抽象类的目的是为了让子类去实现这些抽象方法,并且强制子类必须实现这些方法。在 Python 中,可以通过 abc 模块来实现抽象类。示例代码如下: ```python from abc import ABC, abstractmethod class MyAbstractClass(ABC): @abstractmethod def my_abstract_method(self): pass class MyConcreteClass(MyAbstractClass): def my_abstract_method(self): print("MyConcreteClass's implementation of my_abstract_method") my_object = MyConcreteClass() my_object.my_abstract_method() ``` 接口是一个约定,它描述了一个类应该具有哪些方法,但是并不关心这些方法的实现方式。接口中的方法都是抽象的,没有具体实现。在 Python 中,没有专门的接口语法,但是可以通过多重继承和抽象类来实现接口。示例代码如下: ```python class MyInterface1(ABC): @abstractmethod def my_interface_method1(self): pass class MyInterface2(ABC): @abstractmethod def my_interface_method2(self): pass class MyConcreteClass(MyInterface1, MyInterface2): def my_interface_method1(self): print("MyConcreteClass's implementation of my_interface_method1") def my_interface_method2(self): print("MyConcreteClass's implementation of my_interface_method2") my_object = MyConcreteClass() my_object.my_interface_method1() my_object.my_interface_method2() ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

submarineas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值