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. curl: (7) couldn't connect to host 解决方法

    使用curl命令访问网站时报错: [root@bqh-119 ~]# curl -I www.test.com curl: (7) couldn't connect to host [root@bqh ...

  2. gdb无法单步调试

    使用gdb调试单步程序时如果打印提示“single stepping until exit from function xxx,which has no line number information ...

  3. Go语言——概念

    静态类型.动态类型.潜在类型 静态类型:指在变量声明中示出的那个类型.绝大多数类型都只有静态类型.唯独接口类型的变量例外,他除了拥有静态类型之外,还拥有动态类型. 动态类型:指在运行时与该变量绑定在一 ...

  4. Vue下的package.json

    { "name": "demo2", "version": "1.0.0", "description&quo ...

  5. PAT Basic 1045 快速排序 (25 分)

    著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的 N 个互不相同的正整数的排列,请问 ...

  6. Ubuntu系统---nvidia驱动下载之问题

                                                                             Ubuntu系统---nvidia驱动下载之问题 百度 ...

  7. 用正则表达式处理一个复杂字符串(类似json格式)

    #利用正则输出{}中的内容 str1="""var local=[{provinceCode:'310000',   cityCode:'310100',   text: ...

  8. 通过字节码分析Java方法的静态分派与动态分派机制

    在上一次[https://www.cnblogs.com/webor2006/p/9723289.html]中已经对Java方法的静态分派在字节码中的表现了,也就是方法重载其实是一种静态分派的体现,这 ...

  9. python_面向对象——类之间的依赖关系

    class Dog: def __init__(self,name,age,master): self.name = name self.age = age self.master = master ...

  10. [唐胡璐]Selenium技巧- dataProvider实现数据驱动

    废话不多讲,直接进主题,怎么实现用Excel配置测试数据,用dataProvider来调用测试数据。 jxl目前来看只支持.xls格式的文件,所以我们采用Apache POI来实现对.xlsx的操作, ...