python中的cls到底指的是什么,与self有什么区别?

2018年07月31日 11:13:09 rs勿忘初心 阅读数:7769
 

作者:秦风
链接:https://www.zhihu.com/question/49660420/answer/335991541

一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。

而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。

这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。

  1.  
    class A(object):
  2.  
    a = 'a'
  3.  
    @staticmethod
  4.  
    def foo1(name):
  5.  
    print 'hello', name
  6.  
    def foo2(self, name):
  7.  
    print 'hello', name
  8.  
    @classmethod
  9.  
    def foo3(cls, name):
  10.  
    print 'hello', name

首先定义一个类A,类A中有三个函数,foo1为静态函数,用@staticmethod装饰器装饰,这种方法与类有某种关系但不需要使用到实例或者类来参与。如下两种方法都可以正常输出,也就是说既可以作为类的方法使用,也可以作为类的实例的方法使用。

  1.  
    a = A()
  2.  
    a.foo1('mamq') # 输出: hello mamq
  3.  
    A.foo1('mamq')# 输出: hello mamq

foo2为正常的函数,是类的实例的函数,只能通过a调用。

  1.  
    a.foo2('mamq') # 输出: hello mamq
  2.  
    A.foo2('mamq') # 报错: unbound method foo2() must be called with A instance as first argument (got str instance instead)

foo3为类函数,cls作为第一个参数用来表示类本身. 在类方法中用到,类方法是只与类本身有关而与实例无关的方法。如下两种方法都可以正常输出。

  1.  
    a.foo3('mamq') # 输出: hello mamq
  2.  
    A.foo3('mamq') # 输出: hello mamq

但是通过例子发现staticmethod与classmethod的使用方法和输出结果相同,再看看这两种方法的区别。

既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢
从它们的使用上来看,
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

也就是说在classmethod中可以调用类中定义的其他方法、类的属性,但staticmethod只能通过A.a调用类的属性,但无法通过在该函数内部调用A.foo2()。修改上面的代码加以说明:

  1.  
    class A(object):
  2.  
    a = 'a'
  3.  
    @staticmethod
  4.  
    def foo1(name):
  5.  
    print 'hello', name
  6.  
    print A.a # 正常
  7.  
    print A.foo2('mamq') # 报错: unbound method foo2() must be called with A instance as first argument (got str instance instead)
  8.  
    def foo2(self, name):
  9.  
    print 'hello', name
  10.  
    @classmethod
  11.  
    def foo3(cls, name):
  12.  
    print 'hello', name
  13.  
    print A.a
  14.  
    print cls().foo2(name)

python中的cls到底指的是什么的更多相关文章

  1. python中self cls init的理解

    原创文章,未经允许禁止转载! python中self cls init的理解 python中self cls init的理解

  2. http协议无状态中的 "状态" 到底指的是什么?!

    引子: 最近在好好了解http,发现对介绍http的第一句话[http协议是无状态的,无连接的]就无法理解了:无状态的[状态]到底指的是什么?! 找了很多资料不仅没有发现有一针见血正面回答这个问题的, ...

  3. http协议无状态中的 "状态" 到底指的是什么?!(转载)

    转载自:https://www.cnblogs.com/bellkosmos/p/5237146.html   引子: 最近在好好了解http,发现对介绍http的第一句话[http协议是无状态的,无 ...

  4. Python 中的数字到底是什么?

    花下猫语:在 Python 中,不同类型的数字可以直接做算术运算,并不需要作显式的类型转换.但是,它的"隐式类型转换"可能跟其它语言不同,因为 Python 中的数字是一种特殊的对 ...

  5. javascript中的this到底指什么?

    来自百度知道解释 JavaScript:this是什么? 定义:this是包含它的函数作为方法被调用时所属的对象.说明:这句话有点咬嘴,但一个多余的字也没有,定义非常准确,我们可以分3部分来理解它!1 ...

  6. 理解KNN算法中的k值-knn算法中的k到底指的是什么 ?

    2019-11-09 20:11:26为方便自己收藏学习,转载博文from:https://blog.csdn.net/llhwx/article/details/102652798 knn算法是指对 ...

  7. java项目中classpath路径到底指的是哪里?

    本文转自:http://blog.csdn.net/javaloveiphone/article/details/51994268 1.src不是classpath, WEB-INF/classes和 ...

  8. **Python中的深拷贝和浅拷贝详解

    Python中的深拷贝和浅拷贝详解   这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容.   要说清楚Python中的深浅拷贝,需要 ...

  9. 论python中的作用域

    编程语言从早至今,可以分为面向过程编程.面向函数编程和面向对象编程.BASIC语言是典型的面向过程编程的语言,C语言支持面向函数编程,但不支持面向对象,JAVA只支持面向对象编程,python同时支持 ...

随机推荐

  1. JS 详解 Cookie、 LocalStorage 与 SessionStorage-转载

    记录一下这些知识,有时候用到会忘记,对原文作者表达感谢. 附上原文链接:JS 详解 Cookie. LocalStorage 与 SessionStorage 基本概念 Cookie Cookie 是 ...

  2. LVM——基本概念

    介绍 LVM(Logical Volume Management)是一种存储设备管理技术,它赋予用户权力,汇集和抽象物理存储设备,从而实现更轻松,更灵活的管理. 利用device mapper这个Li ...

  3. python读txt数据报编码错误

    读数据代码: with open(path,'r') as f: for line in f: line = line.strip() 报错: UnicodeDecodeError: 'gbk' co ...

  4. 201871010111-刘佳华《面向对象程序设计(java)》课程学习总结

    201871010111-刘佳华<面向对象程序设计(java)>课程学习总结 课程学习总结(45分) 经历了一个学期的<面向对象程序设计>课程学习,请每位同学完成以下任务: 点 ...

  5. 原生JS实现简单富文本编辑器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. python文件操作知识点总结:写入篇

    文件写入: 文中的两个变量:f 和 f1(截图时被该死的灯泡遮挡住了) 被称作文件对象 或文件句柄(重口味的叫法,感觉很C++,句子又不是刀子,怎么还带柄?) 以逗号为界,open()方法所依赖的3个 ...

  7. selenium报错以及各解决方法

    1.driver.findElement(By.name("wd")).sendKeys("selenium"); 报错:The method sendKeys ...

  8. MAC常用的快捷键

    MAC上剪切文件: 首先command+C 然后command+option+V

  9. 04_mysql安装

    # 安装 [root@localhost ~]# yum install mysql mysql-server -y 报错 [root@ossec-server ~]# yum install mys ...

  10. 12、Spring Boot 2.x 集成 MongoDB

    1.12 Spring Boot 2.x 集成 MongoDB 完整源码: Spring-Boot-Demos