为什么要加@classmethod这个装饰器那。

来源:3-6 Django类视图

qq_拱手河山讨欢_0

2019-01-25

class CommonResponseMixin(object):

@classmethod

def wrap_json_response(cls, data=None, code=None, message=None):
    response = {}
    if not code:
        code = ReturnCode.SUCCESS
    if not message:
        message = ReturnCode.message(code)
    if data:
        response['data'] = data
    response['result_code'] = code
    response['message'] = message
    return response

wrap_json_response这个函数上面加了这个装饰器,我把装饰器去掉也能正常访问。 我百度了下,说的是让这个方法成为类方法,但是我不知道具体用处何在。既然不加也能正常访问,为什么要加那?

写回答

1回答

咚咚呛

2019-01-26

哈哈,这个问题挺有意思的,以下我分几个角度简单回答一下这个问题。


1. 首先是使用方法:

@classmethod 修饰的方法是类方法,相对比的是成员方法。在调用上有以下差别。

# 类方法 不用实例化对象即可调用
CommonResponseMixin.wrap_json_response

# 如果去掉修饰 就变成了成员方法 需要实例化对象才可调用
CommonResponseMixin().wrap_json_response

在使用方法上,类方法的调用方式相比成员方法,要简单一些。


2. 面向对象编程:

第二个角度从面向对象的角度去看待。

在面向对象编程的时候,我们应该怎么选择把一个方法定义成类方法还是成员方法呢?最简单的确定方法就是,方法里面的逻辑是否操作了成员变量,如果操作了成员变量,我们就应该把这个方法定义为成员方法,因为他操作了成员特有的属性而不是类共有的属性。

回到这里,wrap_json_response这个方法知识简单的封装response的一个方法,没有涉及相关成员变量,所以按照刚才面向对象编程的描述,这里应该把它定义为类方法。


3. 编译角度:

反过来想,假设在这里把这个函数定义成成员函数,撇开课程的继承的场景,在没有这个类实例引用的时候,我们需要对这个函数进行调用,我们是不是每次都要先实例化一个这个类的对象出来然后在进行调用。类似的调用方式如下:

CommonResponseMixin().wrap_json_response

这样的调用方法,在__init__函数逻辑简单、调用次数少的时候,还可以接受,如果__init__函数逻辑复杂、调用次数多的话,每次调用都要实例化一个这样的对象,会给系统造成极大不必要的性能损失。


当然啦,这里面提及到的都是非常的细节了,同学们可以作为拓展知识去了解这些。

希望对你有帮助。

4
4
咚咚呛
回复
qq_拱手河山讨欢_0
嗯,我其实是非常鼓励不懂就问的,但是在问之前呢,要先经过自己的认真思考。
2019-01-26
共4条回复

Django+小程序技术打造微信小程序助手

0到1完整项目实战过程,是难得的Django+小程序全栈项目体验。

991 学习 · 507 问题

查看课程