讲解一

一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。

既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢
从它们的使用上来看,

  • @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
  • @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。

    如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
    而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。
    下面上代码。

class A(object):  bar = 1  def foo(self):  print 'foo'  @staticmethod  def static_foo():  print 'static_foo'  print A.bar  @classmethod  def class_foo(cls):  print 'class_foo'  print cls.bar  cls().foo()
###执行
A.static_foo()
A.class_foo()  

输出

static_foo
1
class_foo
1
foo


讲解二

类中最常用的方法是实例方法, 即通过通过实例作为第一个参数的方法。
举个例子,一个基本的实例方法就向下面这个:

class Kls(object):def __init__(self, data):self.data = datadef printd(self):print(self.data)
ik1 = Kls('arun')
ik2 = Kls('seema')
ik1.printd()
ik2.printd()

这会给出如下的输出:

arun
seema


然后看一下代码和示例图片:

  • 1,2参数传递给方法.
  • 3 self参数指向当前实例自身.
  • 4 我们不需要传递实例自身给方法,Python解释器自己会做这些操作的

如果现在我们想写一些仅仅与类交互而不是和实例交互的方法会怎么样呢? 我们可以在类外面写一个简单的方法来做这些,但是这样做就扩散了类代码的关系到类定义的外面. 如果像下面这样写就会导致以后代码维护的困难:

def get_no_of_instances(cls_obj):return cls_obj.no_inst
class Kls(object):no_inst = 0def __init__(self):Kls.no_inst = Kls.no_inst + 1
ik1 = Kls()
ik2 = Kls()
print(get_no_of_instances(Kls))

输出:

2

@classmethod
我们要写一个只在类中运行而不在实例中运行的方法. 如果我们想让方法不在实例中运行,可以这么做:

def iget_no_of_instance(ins_obj):return ins_obj.__class__.no_inst
class Kls(object):no_inst = 0def __init__(self):Kls.no_inst = Kls.no_inst + 1
ik1 = Kls()
ik2 = Kls()
print iget_no_of_instance(ik1)

输出

2

在Python2.2以后可以使用@classmethod装饰器来创建类方法.

class Kls(object):no_inst = 0def __init__(self):Kls.no_inst = Kls.no_inst + 1@classmethoddef get_no_of_instance(cls_obj):return cls_obj.no_inst
ik1 = Kls()
ik2 = Kls()
print ik1.get_no_of_instance()
print Kls.get_no_of_instance()

输出:

2
2

这样的好处是: 不管这个方式是从实例调用还是从类调用,它都用第一个参数把类传递过来.
@staticmethod
经常有一些跟类有关系的功能但在运行时又不需要实例和类参与的情况下需要用到静态方法. 比如更改环境变量或者修改其他类的属性等能用到静态方法. 这种情况可以直接用函数解决, 但这样同样会扩散类内部的代码,造成维护困难.
比如这样:

IND = 'ON'
def checkind():return (IND == 'ON')
class Kls(object):def __init__(self,data):self.data = data
def do_reset(self):if checkind():print('Reset done for:', self.data)
def set_db(self):if checkind():self.db = 'new db connection'print('DB connection made for:',self.data)
ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()

输出:

Reset done for: 12
DB connection made for: 12

如果使用@staticmethod就能把相关的代码放到对应的位置了.

IND = 'ON'
class Kls(object):def __init__(self, data):self.data = data@staticmethoddef checkind():return (IND == 'ON')def do_reset(self):if self.checkind():print('Reset done for:', self.data)def set_db(self):if self.checkind():self.db = 'New db connection'print('DB connection made for: ', self.data)
ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()

输出:

Reset done for: 12
DB connection made for: 12

下面这个更全面的代码和图示来展示这两种方法的不同
@staticmethod 和 @classmethod的不同

class Kls(object):def __init__(self, data):self.data = datadef printd(self):print(self.data)@staticmethoddef smethod(*arg):print('Static:', arg)@classmethoddef cmethod(*arg):print('Class:', arg)
>>> ik = Kls(23)
>>> ik.printd()
23
>>> ik.smethod()
Static: ()
>>> ik.cmethod()
Class: (<class '__main__.Kls'>,)
>>> Kls.printd()
TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead)
>>> Kls.smethod()
Static: ()
>>> Kls.cmethod()
Class: (<class '__main__.Kls'>,)

--------------------- 作者:GeekLeee 来源:CSDN 原文:https://blog.csdn.net/GeekLeee/article/details/52624742?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!

python 类不实例化方法:@staticmethod或@classmethod相关推荐

  1. python方法定义..._解析Python类中的方法定义

    最近在学习类过程中,绑定方法这个概念没有理解透彻,所以在网上找了很多相关博客.文章研究到底是怎么一回事.因为有的文章所陈述与我在python3.5版本实际实验中有些出入,所以经过实践后总结出以下结论. ...

  2. python类的析构方法是什么_python类的析构方法是什么_python类析构

    python __del__ 转自:http://blog.csdn.net/bbdxf/article/details/25774763 最近学习<Python参考手册>学到Class部 ...

  3. python类继承中构造方法_第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解...

    第8.3节Python类的__init__方法深入剖析:构造方法与继承详解 一.    引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类没 ...

  4. php类的实例化方法,php中类的定义和实例化方法

    php中类的定义和实例化方法 发布时间:2020-06-18 11:29:37 来源:亿速云 阅读:57 作者:Leah 这篇文章运用简单易懂的例子给大家介绍php中类的定义和实例化方法,代码非常详细 ...

  5. Python类三种方法,函数传参,类与实例变量

    1 Python的函数传递: 首先所有的变量都可以理解为内存中一个对象的'引用' a = 1 def func(a):a = 2 func(a) print(a) # 1a = 1 def fun(a ...

  6. python类的魔法方法和装饰器

    装饰器 闭包装饰器 装饰器的本质就是一个闭包, 闭包三要素:1 函数嵌套, 2 外部函数返回内部函数的引用, 内部函数使用外部函数的变量 1 使用装饰器简单实现一个登录校验功能 In [1]: use ...

  7. python 类的绑定方法和非绑定方法

    一.绑定方法 1.对象的绑定方法 首先我们明确一个知识点,凡是类中的方法或函数,默认情况下都是绑定给对象使用的.下面,我们通过实例,来慢慢解析绑定方法的应用. class People:def __i ...

  8. 全面解析python类的绑定方法与非绑定方法(转载+自己的消化与理解)

    参考链接来自: https://www.cnblogs.com/vipchenwei/p/7126772.html#_label1 先说下,这篇文章中,其实有这么个事情: 也就是,该文章有的函数后面没 ...

  9. Python类的多种方法,你分得清吗?

    在初学Python过程中,会遇到这样的概念,一个类下面会有多个方法,有的叫类方法.有的叫静态方法,还有的叫实例方法.当调用他们的时候,不免会有点蒙圈,那么他们之间的区别是什么呢? 和类属性一样,类方法 ...

最新文章

  1. ipv6下单播。组播 泛播
  2. 为.Text加了注册模块
  3. mysql pl安装教程_ubuntu 16 mysql安装包安装 (推荐在线安装)
  4. Linux跨平台远程控制
  5. SPSS操作(四):系统聚类分析
  6. 【原】android获取设备基本信息
  7. paging library java_Android官方分页组件介绍之Paging的使用详解
  8. eclipse+maven远程(自动)部署web项目到tomcat
  9. html csv 中文乱码,csv 中文乱码
  10. 热流体动压润滑matlab_设备润滑知识点(下午见)
  11. PHP微信公众号开发常用功能
  12. linux微信电脑版登录不了,默认Windows与Deepin系统下的微信电脑版目录
  13. 全球及中国钢铁贸易行业销售模式与供给规模预测报告2021版
  14. 古代的人才选拔,哪种制度更好?
  15. 千兆路由器怎么设置网速最快_安装了千兆路由器,为什么下载速度很慢?
  16. 根据两点的经纬度求方位角和距离,等
  17. LeetCode-Hot100-两数之和
  18. 剑指offer 数组中出现次数超过一半的数字
  19. gcc cross compiler 问题
  20. 新加硬盘但计算机里找不着,win10新加的硬盘为什么不显示_win10新加的硬盘不显示恢复方法-win7之家...

热门文章

  1. 机器学习 Python 库 Top 20
  2. 渗透测试之Nmap命令(一)
  3. Golang通道(chan,协程交互数据)
  4. Sparta(斯巴达)——信息收集扫描爆破集成
  5. 【洛谷习题】填涂颜色
  6. Spring IOC BeanDefinition解析
  7. jpa-spring -basic
  8. Java EE业务处理流程与XML的引入
  9. Oracle Segments可以跨多个data files吗?
  10. Educational Codeforces Round 14 - F (codeforces 691F)