找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 15059|回复: 100

Python中staticmethod和classmethod的差别

 火.. [复制链接]

8

主题

415

回帖

2672

积分

高级会员

积分
2672
发表于 2018-9-13 21:24:55 | 显示全部楼层 |阅读模式
Class vs static methods in Python

这篇文章试图表明:什么是staticmethod/classmethod,而且这两者之间的差别.

staticmethod和classmethod均被作为装饰器,用作界说一个函数为”staticmethod”照旧”classmethod”

假如想要相识Python装饰器的底子,可以看 这篇文章(http://www.pythoncentral.io/python-decorators-overview/

Simple, static and class methods

类中最常用到的方法是 实例方法(instance methods), 即,实例对象作为第一个参数通报给函数

比方,下面是一个根本的实例方法

[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Kls[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]data[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]data[color=#006FE0 !important] = [color=teal !important]data

[color=teal !important]    def printd[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=teal !important]print[color=#333333 !important](self[color=#333333 !important].[color=#002D7A !important]data[color=#333333 !important])

[color=#002D7A !important]ik1[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]([color=#DD1144 !important]'arun'[color=#333333 !important])
[color=#002D7A !important]ik2[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]([color=#DD1144 !important]'seema'[color=#333333 !important])

[color=#002D7A !important]ik1[color=#333333 !important].[color=teal !important]printd[color=#333333 !important]()
[color=#002D7A !important]ik2[color=#333333 !important].[color=teal !important]printd[color=#333333 !important]()

得到的输出:

[color=teal !important]arun
[color=#002D7A !important]seema

调用关系图:





检察代码和图解:


[color=#009999 !important]1[color=#006FE0 !important]/[color=#009999 !important]2[color=#006FE0 !important] 参数通报给函数
[color=#009999 !important]3[color=#006FE0 !important]   self参数指向实例自己[color=#006FE0 !important]
[color=#009999 !important]4[color=#006FE0 !important]   我们不必要显式提供实例,表明器自己会处置惩罚


如果我们想仅实现类之间交互而不是通过实例?我们可以在类之外创建一个简朴的函数来实现这个功能,但是将会使代码扩散到类之外,这个大概对将来代码维护带来题目。


比方:


[color=teal !important]def get_no_of_instances[color=#333333 !important]([color=#002D7A !important]cls_obj[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    return[color=#006FE0 !important] [color=#002D7A !important]cls_obj[color=#333333 !important].[color=teal !important]no_inst

[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Kls[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=#002D7A !important]no_inst[color=#006FE0 !important] = [color=#009999 !important]0

[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=#002D7A !important]Kls[color=#333333 !important].[color=#002D7A !important]no_inst[color=#006FE0 !important] = [color=#002D7A !important]Kls[color=#333333 !important].[color=#002D7A !important]no_inst[color=#006FE0 !important] + [color=#009999 !important]1

[color=#002D7A !important]ik1[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]()
[color=#002D7A !important]ik2[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]()

[color=teal !important]print[color=#333333 !important]([color=teal !important]get_no_of_instances[color=#333333 !important]([color=#002D7A !important]Kls[color=#333333 !important]))


效果:


2


The Python @classmethod


如今我们要做的是在类里创建一个函数,这个函数参数是类对象而不是实例对象.


在上面谁人实现中,假如要实现不获取实例,必要修改如下:


[color=teal !important]def iget_no_of_instance[color=#333333 !important]([color=#002D7A !important]ins_obj[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    return[color=#006FE0 !important] [color=#002D7A !important]ins_obj[color=#333333 !important].[color=#002D7A !important]__class__[color=#333333 !important].[color=teal !important]no_inst

[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Kls[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=#002D7A !important]no_inst[color=#006FE0 !important] = [color=#009999 !important]0

[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=#002D7A !important]Kls[color=#333333 !important].[color=#002D7A !important]no_inst[color=#006FE0 !important] = [color=#002D7A !important]Kls[color=#333333 !important].[color=#002D7A !important]no_inst[color=#006FE0 !important] + [color=#009999 !important]1

[color=#002D7A !important]ik1[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]()
[color=#002D7A !important]ik2[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]()
[color=teal !important]print iget_no_of_instance[color=#333333 !important]([color=#002D7A !important]ik1[color=#333333 !important])

效果
[color=#009999 !important]2


可以利用Python2.2引入的新特性,利用@classmethod在类代码中创建一个函数


[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Kls[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=#002D7A !important]no_inst[color=#006FE0 !important] = [color=#009999 !important]0

[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=#002D7A !important]Kls[color=#333333 !important].[color=#002D7A !important]no_inst[color=#006FE0 !important] = [color=#002D7A !important]Kls[color=#333333 !important].[color=#002D7A !important]no_inst[color=#006FE0 !important] + [color=#009999 !important]1

[color=#006FE0 !important]    [color=#333333 !important]@[color=teal !important]classmethod
[color=teal !important]    def get_no_of_instance[color=#333333 !important]([color=#002D7A !important]cls_obj[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        return[color=#006FE0 !important] [color=#002D7A !important]cls_obj[color=#333333 !important].[color=teal !important]no_inst

[color=#002D7A !important]ik1[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]()
[color=#002D7A !important]ik2[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]()

[color=teal !important]print [color=#002D7A !important]ik1[color=#333333 !important].[color=teal !important]get_no_of_instance[color=#333333 !important]()
[color=teal !important]print [color=#002D7A !important]Kls[color=#333333 !important].[color=teal !important]get_no_of_instance[color=#333333 !important]()


We get the following output:


[color=#009999 !important]2
[color=#009999 !important]2


The Python @staticmethod


通常,有许多环境下一些函数与类相干,但不必要任何类或实例变量就可以实现一些功能.


好比设置情况变量,修改另一个类的属性等等.这种环境下,我们也可以利用一个函数,一样会将代码扩散到类之外(难以维护)


下面是一个例子:


[color=#002D7A !important]IND[color=#006FE0 !important] = [color=#DD1144 !important]'ON'

[color=teal !important]def checkind[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]    return[color=#006FE0 !important] [color=#333333 !important]([color=#002D7A !important]IND[color=#006FE0 !important] == [color=#DD1144 !important]'ON'[color=#333333 !important])

[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Kls[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important],[color=#002D7A !important]data[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]data[color=#006FE0 !important] = [color=teal !important]data

[color=teal !important]    def do_reset[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        if[color=#006FE0 !important] [color=teal !important]checkind[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]            [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'Reset done for:'[color=#333333 !important],[color=#006FE0 !important] self[color=#333333 !important].[color=#002D7A !important]data[color=#333333 !important])

[color=#006FE0 !important]    [color=teal !important]def set_db[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        if[color=#006FE0 !important] [color=teal !important]checkind[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]            self[color=#333333 !important].[color=#002D7A !important]db[color=#006FE0 !important] = [color=#DD1144 !important]'new db connection'
[color=#006FE0 !important]            [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'DB connection made for:'[color=#333333 !important],self[color=#333333 !important].[color=#002D7A !important]data[color=#333333 !important])

[color=#002D7A !important]ik1[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]([color=#009999 !important]12[color=#333333 !important])
[color=#002D7A !important]ik1[color=#333333 !important].[color=teal !important]do_reset[color=#333333 !important]()
[color=#002D7A !important]ik1[color=#333333 !important].[color=teal !important]set_db[color=#333333 !important]()


效果:


[color=teal !important]Reset done for[color=#006FE0 !important]: [color=#009999 !important]12
[color=teal !important]DB connection made for[color=#006FE0 !important]: [color=#009999 !important]12


如今我们利用@staticmethod, 我们可以将全部代码放到类中


[color=#002D7A !important]IND[color=#006FE0 !important] = [color=#DD1144 !important]'ON'

[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Kls[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]data[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]data[color=#006FE0 !important] = data

[color=#006FE0 !important]    [color=#333333 !important]@[color=teal !important]staticmethod
[color=teal !important]    def checkind[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]        return[color=#006FE0 !important] [color=#333333 !important]([color=#002D7A !important]IND[color=#006FE0 !important] == [color=#DD1144 !important]'ON'[color=#333333 !important])

[color=#006FE0 !important]    [color=teal !important]def do_reset[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        if[color=#006FE0 !important] self[color=#333333 !important].[color=teal !important]checkind[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]            [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'Reset done for:'[color=#333333 !important],[color=#006FE0 !important] self[color=#333333 !important].[color=#002D7A !important]data[color=#333333 !important])

[color=#006FE0 !important]    [color=teal !important]def set_db[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        if[color=#006FE0 !important] self[color=#333333 !important].[color=teal !important]checkind[color=#333333 !important]()[color=#006FE0 !important]:
[color=#006FE0 !important]            self[color=#333333 !important].[color=#002D7A !important]db[color=#006FE0 !important] = [color=#DD1144 !important]'New db connection'
[color=#006FE0 !important]        [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'DB connection made for: '[color=#333333 !important],[color=#006FE0 !important] self[color=#333333 !important].[color=#002D7A !important]data[color=#333333 !important])

[color=#002D7A !important]ik1[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]([color=#009999 !important]12[color=#333333 !important])
[color=#002D7A !important]ik1[color=#333333 !important].[color=teal !important]do_reset[color=#333333 !important]()
[color=#002D7A !important]ik1[color=#333333 !important].[color=teal !important]set_db[color=#333333 !important]()


得到的效果:


[color=teal !important]Reset done for[color=#006FE0 !important]: [color=#009999 !important]12
[color=teal !important]DB connection made for[color=#006FE0 !important]: [color=#009999 !important]12


How @staticmethod and @classmethod are different


[color=#800080 !important]class[color=#006FE0 !important] [color=teal !important]Kls[color=#333333 !important]([color=#800080 !important]object[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]    [color=teal !important]def __init__[color=#333333 !important](self[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]data[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        self[color=#333333 !important].[color=#002D7A !important]data[color=#006FE0 !important] = [color=teal !important]data

[color=teal !important]    def printd[color=#333333 !important](self[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=teal !important]print[color=#333333 !important](self[color=#333333 !important].[color=#002D7A !important]data[color=#333333 !important])

[color=#006FE0 !important]    [color=#333333 !important]@[color=teal !important]staticmethod
[color=teal !important]    def smethod[color=#333333 !important]([color=#006FE0 !important]*[color=#002D7A !important]arg[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'Static:'[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]arg[color=#333333 !important])

[color=#006FE0 !important]    [color=#333333 !important]@[color=teal !important]classmethod
[color=teal !important]    def cmethod[color=#333333 !important]([color=#006FE0 !important]*[color=#002D7A !important]arg[color=#333333 !important])[color=#006FE0 !important]:
[color=#006FE0 !important]        [color=teal !important]print[color=#333333 !important]([color=#DD1144 !important]'Class:'[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]arg[color=#333333 !important])


调用


[color=#006FE0 !important]>>> [color=#002D7A !important]ik[color=#006FE0 !important] = [color=teal !important]Kls[color=#333333 !important]([color=#009999 !important]23[color=#333333 !important])
[color=#006FE0 !important]>>> [color=#002D7A !important]ik[color=#333333 !important].[color=teal !important]printd[color=#333333 !important]()
[color=#009999 !important]23
[color=#006FE0 !important]>>> [color=#002D7A !important]ik[color=#333333 !important].[color=teal !important]smethod[color=#333333 !important]()
[color=#800080 !important]Static[color=#006FE0 !important]: [color=#333333 !important]()
[color=#006FE0 !important]>>> [color=#002D7A !important]ik[color=#333333 !important].[color=teal !important]cmethod[color=#333333 !important]()
[color=#800080 !important]Class[color=#006FE0 !important]: [color=#333333 !important](,)
[color=#006FE0 !important]>>> [color=#002D7A !important]Kls[color=#333333 !important].[color=teal !important]printd[color=#333333 !important]()
[color=#002D7A !important]TypeError[color=#006FE0 !important]: [color=teal !important]unbound method printd[color=#333333 !important]()[color=#006FE0 !important] [color=teal !important]must be called with Kls instance as[color=#006FE0 !important] [color=teal !important]first argument[color=#006FE0 !important] [color=#333333 !important]([color=teal !important]got nothing [color=#002D7A !important]instead[color=#333333 !important])
[color=#006FE0 !important]>>> [color=#002D7A !important]Kls[color=#333333 !important].[color=teal !important]smethod[color=#333333 !important]()
[color=#800080 !important]Static[color=#006FE0 !important]: [color=#333333 !important]()
[color=#006FE0 !important]>>> [color=#002D7A !important]Kls[color=#333333 !important].[color=teal !important]cmethod[color=#333333 !important]()
[color=#800080 !important]Class[color=#006FE0 !important]: [color=#333333 !important](,)


图解







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
工控课堂 www.gkket.com

10

主题

377

回帖

2757

积分

高级会员

积分
2757
发表于 2018-9-20 07:25:12 | 显示全部楼层
论坛有你更精彩!
工控课堂 www.gkket.com

8

主题

415

回帖

2672

积分

高级会员

积分
2672
 楼主| 发表于 2018-9-21 20:16:29 | 显示全部楼层
真是难得给力的帖子啊。
工控课堂 www.gkket.com

8

主题

454

回帖

2305

积分

高级会员

积分
2305
发表于 2018-9-21 20:41:33 | 显示全部楼层
党的好公民,人民的好公仆。。。
工控课堂 www.gkket.com

11

主题

428

回帖

2354

积分

高级会员

积分
2354
发表于 2018-9-23 12:52:04 | 显示全部楼层
论坛有你更精彩!
工控课堂 www.gkket.com

9

主题

429

回帖

2537

积分

高级会员

积分
2537
发表于 2018-9-24 10:17:03 | 显示全部楼层
淡定,淡定,淡定……
工控课堂 www.gkket.com

0

主题

451

回帖

2972

积分

高级会员

积分
2972
发表于 2018-9-24 14:11:23 | 显示全部楼层
我顶,我顶,我顶顶顶
工控课堂 www.gkket.com

0

主题

438

回帖

1973

积分

高级会员

积分
1973
发表于 2018-9-26 08:54:17 | 显示全部楼层
加油,加油,不要沉下去,我是最热贴
工控课堂 www.gkket.com

16

主题

433

回帖

2536

积分

高级会员

积分
2536
发表于 2018-9-26 16:33:33 | 显示全部楼层
楼主您的技术水准,我最服你,其他都是浮云
工控课堂 www.gkket.com

0

主题

466

回帖

2545

积分

高级会员

积分
2545
发表于 2018-9-26 21:15:43 | 显示全部楼层
激动人心,无法言表!
工控课堂 www.gkket.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|手机版|免责声明|本站介绍|工控课堂 ( 沪ICP备20008691号-1 )

GMT+8, 2025-12-22 22:21 , Processed in 0.102462 second(s), 30 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表