python的@classmethod和@staticmethod详解
发布日期:2021-10-03 22:59:26 浏览次数:32 分类:技术文章

本文共 3692 字,大约阅读时间需要 12 分钟。

Python面向对象编程中,类中定义的方法有的使用@classmethod 修饰,有的使用@staticmethod 修饰,还有的不带任何修饰方法。他们之间具体有哪些区别,具体的使用场景是怎么样的,这里使用例子解释一下。只是基于自己在使用过程中的理解,如果有误欢迎指正。

1普通方法:

特点:

1 必须首先有类的实例, 通过实例调用。

2 方法必须至少有一个参数指向实例本身。缺少参数,运行会报错

1.1错误例子1 通过类直接调用普通方法

import platformclass TestMe(object):    def __init__(self, name):        self._name=name    def normalfunc(self):        print("normal names")clme=TestMe("Hello")TestMe.normalfunc()

 报如下错误:

Traceback (most recent call last):  File "./classmethod.py", line 20, in 
TestMe.normalfunc()TypeError: normalfunc() missing 1 required positional argument: 'self'

1.2 错误例子2 普通方法不定义任何参数

import platformclass TestMe(object):    def __init__(self, name):        self._name=name    def normalfunc():        print("normal name")clme=TestMe("Hello")clme.normalfunc()

运行时,会报如下错误:

Traceback (most recent call last):  File "./classmethod.py", line 24, in 
clme.normalfunc()TypeError: normalfunc() takes 0 positional arguments but 1 was given

1.3 正确用法

 

import platformclass TestMe(object):    def __init__(self, name):        self._name=name    def normalfunc(self):        print("normal names:%s"%self._name)clme=TestMe("Hello")clme.normalfunc()

 

2 @classmethod方法

特点:

1 classmethod是属于类的方法,可以不通过类的实例直接使用类名调用。

2 方法的第一个参数必须是类的引用

3 既可以通过类的实例调用,也可以直接使用类名调用

4 继承类也继承相应的classmethod方法

2.1 错误例子1不定义参数

import platformclass TestMe(object):    def __init__(self, name):        self._name=name    @classmethod    def classfunc():        print("class name is %s"%"test")clme=TestMe("Hello")clme.classfunc()TestMe.classfunc()

报如下错误:

Traceback (most recent call last):  File "./classmethod.py", line 20, in 
clme.classfunc()TypeError: classfunc() takes 0 positional arguments but 1 was given

方法必须有一个参数

2.2 正确例子

import platformclass TestMe(object):    def __init__(self, name):        self._name=name        @classmethod    def classfunc(cls, rawname):        name = "Prefix_" + rawname        print("class name is %s"%name)        return cls(name)    def normalfunc(self):        print("normal names:%s"%self._name)class childTest(TestMe):    def __init__(self, name):        super().__init__(name)clme = TestMe("Hello")nextobj = clme.classfunc("next") #可以通过实例调用thirdobj = TestMe.classfunc("third") #可以通过类名直接调用clme.normalfunc()nextobj.normalfunc()thirdobj.normalfunc()childobj = childTest.classfunc("child")childobj.normalfunc()

执行结果:

normal names:Hellonormal names:Prefix_nextnormal names:Prefix_thirdnormal names:Prefix_child

3 @staticmethod方法

特点:

@staticmethod与@classmethod很相似,仅有的区别是@staticmethod方法的第一个参数不是类,也可以根本不需要参数

示例:

import platformclass TestMe(object):    def __init__(self, name):        self._name=name    @classmethod    def classfunc(cls, rawname):        name = "Prefix_" + rawname        return cls(name)    @staticmethod    def staticfunc():        print("static name is %s"%"test static")    def normalfunc(self):        print("normal names:%s"%self._name)class childTest(TestMe):    def __init__(self, name):        super().__init__(name)clme = TestMe("Hello")nextobj = clme.classfunc("next")thirdobj = TestMe.classfunc("third")clme.normalfunc()nextobj.normalfunc()thirdobj.normalfunc()childobj = childTest.classfunc("child")childobj.normalfunc()clme.staticfunc()TestMe.staticfunc()childobj.staticfunc()childTest.staticfunc()

输出:

normal names:Hellonormal names:Prefix_nextnormal names:Prefix_thirdnormal names:Prefix_childstatic name is test staticstatic name is test staticstatic name is test staticstatic name is test static

 

4 总结

classmethod与staticmethod用法类似,大多数情况下,classmethod可以通过staticmethod代替,在通过类调用时,这两者对于调用者来说是不可区分的。

这两者的区别在于,classmethod增加了一个对实际调用类的引用,这样可以:

  1. 方法可以判断出自己是通过基类被调用,还是通过某个子类被调用
  2. 通过子类调用时,方法可以返回子类的实例而非基类的实例
  3. 通过子类调用时,方法可以调用子类的其他classmethod

转载地址:https://blog.csdn.net/lclfans1983/article/details/109504869 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:InfluxDB配置总结-通过配置参数和Curl命令
下一篇:python获取CPU和操作系统类型

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月22日 06时58分35秒