Python中的 staticmethod 和 classmethod

众所周知,类是创建实例的模板,而实例是一个个具体的对象,各个实例拥有的数据相互独立、互不影响。

在类中定义的函数称为方法,主要有三种:实例方法、类方法、静态方法

class A:

    def instance_method(self, n):
        print('self', self)

    @classmethod
    def class_method(cls, n):
        print('cls', cls)

    @staticmethod
    def static_method():
        print('this is a static method')

上面类 A 定义的三个方法分别是实例方法、类方法、静态方法,下面我们来详细分析

实例方法

不带装饰器的实例方法在类定义中是最常见的:

定义中,传入的第一个参数必须是 self,表示实例本身,在其中可使用 self.attr 获取实例的属性。

a = A()
a.instance_method(2)
print(A.bar)
print(a.bar)

下面是程序运行结果:

self <__main__.A object at 0x0000028554C87E48>
grg
grg

当我们创建了实例 a 之后,调用 a.instance_method(2) 时,实例 a 会被自动传入函数作为 self 参数。

如果我们调用 A.instance_method(2) 时会发生什么呢?即,类能不能调用实例方法?

Traceback (most recent call last):
  File "I:\Program Code\Python\test2.py", line 32, in <module>
    A.instance_method(2)
TypeError: instance_method() missing 1 required positional argument: 'n'

可以看到,数字 2 被传入 self 参数了,所以才会提示缺少一个位置参数 n,所以,实例方法不能由类调用。

顺便提一句,属性也分实例属性和类属性,上例直接定义的是类属性,类和类实例都可以访问。类中定义的方法也可以无限制访问这个类属性。

通过 __init__(self,attr) 定义的是实例属性,只有实例能访问,类不能访问。类中定义的属性只有传进了 self 参数的方法(通常就是实例方法)可访问。

classmethod

无需实例化,但与实例方法第一个参数必须是 self 类似,类方法第一个参数表示类自身的 cls 参数,可以来调用类的属性、类的方法、类的实例化对象等

a.class_method(2)
A.class_method(2)

观察上面代码的运行结果:

cls <class '__main__.A'>
cls <class '__main__.A'>

可知,类方法既可以由类调用,也可以由实例调用。

再来看一个例子:

class Book(object):
    def __init__(self, title):
        self.title = title

    @classmethod
    def create(cls, title):
        book = cls(title)
        return book


book1 = Book('A song of Ice and Fire')
book2 = Book.create('The Marvel')
print(book1.title)
print(book2.title)

运行结果如下:

A song of Ice and Fire
The Marvel

上面,类方法创建了一个类实例。

staticmethod

无需 self 参数,无需 cls 参数,直接声明一个静态方法,可无需实例化,直接由类调用,也可实例化后调用。

带 staticmethod 装饰器定义的就是静态方法,与普通函数没有区别,可以不加参数,可以加任意参数,不必传入 self ,既可以由实例调用,也可以由类调用。

A.static_method()
a.static_method()

运行结果如下:

this is a static method
this is a static method

总结

实例方法只能由实例调用,类方法和静态方法可以由实例或类调用。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,707评论 2 9
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,800评论 6 13
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,067评论 1 32
  • 今天是很不寻常的一天,今天也是感受另外一种生命的一天。放下了,完美放下了,放下了,别人对自己的评判,以及别人对自己...
    陈琦不黑阅读 174评论 0 2
  • 嗨,静言,今天是2017年的第一天。2016的你过得怎样? happy for everyday,just a l...
    jamieT2311阅读 235评论 0 2