文章首发于 微信公众号:Python编程时光

这个标题「静态方法其实暗藏玄机」其实只是该文章的一个知识点。或许有些标题党,但没有关系,我相信有不少人对此并没有深入研究他们,不信我问你三个问题,你看能否答上来。

1、Python2.x和3.x中,函数和方法的区分有什么不同?

2、有了类/实例方法和普通函数,为什么还会有静态方法?

3、Python3.x 中,静态方法有几种写法?

带着这三个问题,你可以尝试在下文中寻找答案。


在 Python 2 中的函数和方法的区别,十分清晰,很好分辨。但在 Python3中,我却发现完全又是另一套准则。

首先先来 Python2 的(以下在 Python2.7中测试通过)

可以得出结论:

1、普通函数(未定位在类里),都是函数。

2、静态方法(@staticmethod),都是函数。

3、类方法(@classmethod),都是方法。

4、实例方法(首参数为self且非静态、非类方法的),都是方法。

你一定想说,类方法和实例方法,是方法没错呀,毕竟名字本身就有方法,普通函数是函数,我也理解呀。那静态方法,为什么不是方法而是函数呢?

名字只是一个外在的表面称呼,你能说「赵铁男」就一定是汉子吗?

我的理解是:方法是一种和对象(实例或者类)绑定后的函数。

类方法的首参是cls,调用时,无需显示传入。实例方法首参是self,调用时,也无需显示传入。

而静态方法,其实和普通函数没啥区别,唯一的区别就是,他定义的位置被放在了类里,做为类或者实例的一个函数。

那你肯定又要问了,既然静态方法和普通函数都是一样的,为什么要刻意将它放在类里呢?

我上面说了,放在类里定义,就可以让它成为类的一个工具函数,这就像你身上随身携带了一把刀,这把刀与你本人并没有什么直接关系,唯一的联系就是这把刀是你的,而你把它带在身上,无论你去到哪里,只要需要,你就可以直接拿出来用上。对比将函数放在类外面,缺点是什么呢?就是当你出门在外(在别的模块里)发现你要用刀的时候,还要特地跑一趟去商店买一把刀(import 这个函数)。

另外,我觉得静态方法在业务和设计上的意义,会更多一些。

一般静态方法是做为类或者实例的一个工具函数,比如对变量的做一个合法性的检验,对数据进行序列化反序列化操作等等。

说完了 Python2 ,再来说说Python3.

以前我觉得 Python2 对于方法和函数的界线更加清晰,但接触了 Python3,我反而觉得Python3里方法和函数的区分似乎更加合理。

还是刚刚那段代码,我更改了解释器为Python3.6(以下在 Python3.6中测试通过)

和Python2的唯一区别是,People.jump 在Python3 中变成了函数。

这一下颠覆了你刚刚才建立起来的知识体系有木有?

先别急,我再做个试验,也许你就知道了。

在 Python2中

执行People.jump('hello'),会报错说,jump的首参必须为People的实例对象,这可以理解,毕竟jump定义时,第一个参数为self。

在 Python3中

你可以发现,这里的jump的首参不再要求是 People 的一个实例,而可以是任意的对象,比如我使用字符串对象,也没有报错。

也就是说,当你往jump中传入的首参为People的实例时,jump 就是方法,而当你传入的首参不是People的实例对象时,jump就是函数。

你看,多么灵活呀。

再总结一下,在Python3中:

1、普通函数(未定位在类里),都是函数。

2、静态方法(@staticmethod),都是函数。

3、类方法(@classmethod),都是方法。

4、方法和函数区分没有那么明确,而是更加灵活了,一个函数有可能是方法也有可能是函数。

你肯定又要问了,那这是不是就意味着,Python3 中静态方法,可以不用再使用@staticmethod 装饰了呢,反正Python3都可以识别。

这是个好问题,是的,可以不用指定,但是最好指定,如果你不指定,你调用这个方法只能通过People.jump,而不能通过 self.jump了,因为首参不是 self,而如果使用@staticmethod 就可以使用self.jump。

所以说这是一个规范,就像类的私有方法,规范要求外部最好不要调用,但这不是强制要求,不是说外部就不能调用。

写这篇文章的起源,是前两天有位读者在交流里问到了相关的问题,正好没什么主题可以写,就拿过来做为素材整理一下,也正好没有写过静态方法、类方法的内容,没想到简单的东西,也能写出这么多的内容出来。

Python静态方法,其实暗藏玄机的更多相关文章

  1. python 静态方法、类方法(二)

    <Python静态方法.类方法>一文中曾用在类之外生成函数的方式,来计算类的实例的个数.本文将探讨用静态方法和类方法来实现此功能. 一使用静态方法统计实例 例1.static.py # - ...

  2. CSS3中:nth-child和:nth-of-type的区别深入理解。 关于:nth-child和:nth-of-type的区别之前一直没太注意,经深入理解才发现里面其实暗藏玄机

    关于:nth-child和:nth-of-type的区别之前一直没太注意.最近打算深入了解一些CSS3,才发现里面其实暗藏玄机. :nth-child可以选择父元素下的字元素,:nth-of-type ...

  3. Python静态方法(staticmethod)和类方法(classmthod)

    Python静态方法(staticmethod)和类方法(classmthod)翻了翻之前的笔记,也刚好看到一篇不错的blog,关于静态方法和类方法的,方便以后查阅,就写在这里了,废话不多说,直接上代 ...

  4. Python 静态方法、类方法和属性方法

    Python 静态方法.类方法和属性方法 静态方法(staticmethod) staticmethod不与类或者对象绑定,类和实例对象都可以调用,没有自动传值效果,Python内置函数staticm ...

  5. 超耐心地毯式分析,来试试这道看似简单但暗藏玄机的Promise顺序执行题

    壹 ❀ 引 就在昨天,与朋友聊到JS基础时,她突然想起之前在面试时,遇到了一道难以理解的Promise执行顺序题.由于我之前专门写过手写promise的文章,对于部分原理也还算了解,出于兴趣我便要了这 ...

  6. Python 静态方法、类方法

    今天我们来讨论一下Python类中所存在的特殊方法--静态方法.类方法. 一.定义 静态方法: 一种简单函数,符合以下要求: 1.嵌套在类中. 2.没有self参数. 特点: 1.类调用.实例调用,静 ...

  7. python 静态方法,类方法 ,类的继承

    转自:  http://cowboy.1988.blog.163.com/blog/static/75105798201091141521583/ 1.关于定义类的一些奇特之处  今天在Python中 ...

  8. python静态方法和类方法

    静态方法和类方法在python2.2中被引用,经典类和新式类都可以使用.同时,一对内建函数:staticmethod和classmethod被引入,用来转化类中某一方法为这两种方法之一. 静态方法: ...

  9. python静态方法类方法属性方法

    Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的: 1)静态方法无需传入self参数,类成员方法需传入代表本类的cls参数: 2)从第1条,静态方法是无法访问 ...

随机推荐

  1. WPF自定义TextBox及ScrollViewer

    原文:WPF自定义TextBox及ScrollViewer 寒假过完,在家真心什么都做不了,可能年龄大了,再想以前那样能专心坐下来已经不行了.回来第一件事就是改了项目的一个bug,最近又新增了一个新的 ...

  2. 在python3下用PIL做图像处理

    Python Imaging Library (PIL)是python下的图像处理模块,支持多种格式,并提供强大的图形与图像处理功能. 目前PIL的官方最新版本为1.1.7,支持的版本为python ...

  3. 031 二进制1的数量(keep it up, 看到这个问题,刚开始有点蒙)

    剑指offer在标题中:http://ac.jobdu.com/problem.php?pid=1513 题目描写叙述: 输入一个整数,输出该数二进制表示中1的个数.当中负数用补码表示. 输入: 输入 ...

  4. 在运行Hfile的MR如果任务client结束OOM

    在运行MR将HDFS转换成HFile什么时候.例如,会发生以下的异常: 14/07/09 18:02:59 INFO mapred.JobClient:  map 83% reduce 0% 14/0 ...

  5. 食谱API自由和开放接口-为了发展自己的健康厨房APP应用

    什么时候健康厨房 (cook.yi18.net)上线后,基于接口的须要,就非常快就完毕的食谱API接口的开发 文档地址:http://doc.yi18.net/cookapidoc 菜谱食谱API , ...

  6. SequenceType 与 GeneratorType

    Swift 语言中提供了一种 for .. in 语法的形式,用于遍历集合,比如对于 Array 类型,就可以用 for .. in 来进行遍历.这个语法在很多其他语言中也有提供,省去了我们定义下标的 ...

  7. WPF x:static的使用

    <Window x:Class="XamlTest.Window1"        xmlns="http://schemas.microsoft.com/winf ...

  8. WPF控件的一些特殊应用

    1 checkbox.IsChecked 返回的是bool?类型,需要用bool强转,或者直接和bool类型比较,将发生隐形转换 2 RadioButton有分组属性GroupName

  9. Android各版本对应的SDK和JDK版本

    原文:Android各版本对应的SDK和JDK版本 一.Android各版本对应的SDK版本: 平台版本 SDK版本 版本名称 Android 8.0 26 Oreo Android 7.1 25 N ...

  10. 怎样解决python dataframe loc,iloc循环处理速度很慢的问题

    怎样解决python dataframe loc,iloc循环处理速度很慢的问题 1.问题说明 最近用DataFrame做大数据 处理,发现处理速度特别慢,追究原因,发现是循环处理时,loc,iloc ...