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. Python For嵌套循环 图形打印X型 nested loop - 练习题答案

    上一篇:Python For嵌套循环 图形打印X型 nested loop - 练习题 上一篇留的Python For嵌套循环 图形打印X型练习题的答案. 由于网上很多嵌套循环都是C++语言写的,用P ...

  2. visual studio code(vscode) 配置在terminal进行运行代码并且支持c++11特性

    1.点击设置 点击CodeRunner的小齿轮,点击configure extension settings 2.点击映射 点击executor map中的Edit in settings.json ...

  3. 个人作业-Alpha项目测试—luomei1547

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/ 这个作业要求在哪里 https://edu.cnbl ...

  4. ThreadLocal 是什么?(未完成)有哪些使用场景?(未完成)

    ThreadLocal 是什么?(未完成)有哪些使用场景?(未完成)

  5. Codeforces 348 D - Turtles

    D - Turtles 思路: LGV 定理 (Lindström–Gessel–Viennot lemma) 从{\(a_1\),\(a_2\),...,\(a_n\)} 到 {\(b_1\),\( ...

  6. Python 类和对象(2)

    上文讲到 类 = 属性 + 方法 今天来讲一下方法里常见的一个特殊的方法: 名字叫 __init__ 的构造方法 1.特殊的方法 :__init__ 该方法在我们实例化类的时候,python就自动调用 ...

  7. Python 之 PyMySQL 安装和使用

    Python具有内置的SQLite支持. 在本节中,我们将学习使用MySQL的相关概念和知识. 在早期Python版本一般都使用MySQLdb模块,但这个MySQL的流行接口与Python 3不兼容. ...

  8. nginx添加模块记录

    查看现有nginx的编译参数: [root@iZbp1d0dkjhfmxnxp7wuhmZ nginx-1.12.2]# nginx -Vnginx version: nginx/1.12.2buil ...

  9. [转]Linux 桌面玩家指南:20. 把 Linux 系统装入 U 盘打包带走

    原文:https://www.cnblogs.com/youxia/p/LinuxDesktop020.html ------------------------------------------- ...

  10. ASP.Net参数传递小结

    同一页面.aspx与.aspx.cs之间参数传递 1. .aspx.cs接收.aspx的参数:由于.aspx和.aspx.cs为继承关系,所以.aspx.cs可以直接对.aspx中的ID进行值提取,具 ...