很多书上都不告诉你,Python类中3个方法的秘密

浏览: 1497

这是菜鸟学python的第39篇原创文章


阅读本文大概需要9分钟

类相当于一个容器,将状态(数据属性)和一些行为(方法)包裹在一起,今天我们就来讲讲Python中的方法.

  • Python中的方法分为3种,一般的书对这几个概念都没有仔细讲,我觉得把这些概念弄清楚,对深入了解类是很有必要的,不然设计类的时候根本写不出真正的OOP.

  • 在Python中定义类的方法和函数都使用def语句,就像定义其他的函数一样来指定其行为.本质上方法其实就是函数

要点:

  • 类的实例方法

  • 类的静态函数

  • 类方法

  • 类方法,静态函数,实例方法之间调用关系


1.类的实例方法

类的实例方法一般有一个显著的特征就是会带有self参数,它的第一个正式参数名为self(这参数有点类似java里面的this),这些方法会访问实例的属性.

看下面的实例代码:


揭秘一下这个调用的过程:


1).step1,step2把参数'arun','seema'传给__init__()里面的data

2).step3 self参数就是ik1对象实例的引用

3).在step4调用printd()这个实例函数的时候,我们不需要把ik1传递self,python自动帮你搞定

2.类的静态函数

类中的方法一般有self的方法也叫绑定对象方法,那Python中有没有不带self,当然有的,静态函数方法就是其中一个

  • 静态方法需要有一个修饰关键字staticmethod,注意前面有一个@,连起来@staticmethod表示下面声明的是一个静态函数方法,

  • 这是Python中的一种特殊用法,其实就是用了一个装饰器的技巧(关于装饰器是Python中复杂的概念之一,本文先不讲后面会详细给大家讲,大家在用web框架比如flask里面会大量用到装饰器的概念)

那么Python中为啥要有静态函数呢:

场景就是和类相关的操作,但是又不会依赖和改变类、实例的状态,比如经常有跟类有关系的函数,我们希望它在运行时又不需要实例和类参与的情况下直接就能调用。调用静态方法可以无需创建对象


举个简单的例子:

有一个机器人的类,有两个方法重启(do_Reset)和保存数据库(save_DB),这两个方法操作之前都需要检查指令


robot1 = Robot('No1_Machine')
robot1.do_Reset()
robot1.save_DB()
>>
Reset done for :No1_Machine
DB connection ready for: No1_Machine
robot2 = Robot('No2_Machine')
robot2.do_Reset()
robot2.save_DB()
>>
Reset done for :No2_Machine
DB connection ready for: No2_Machine


这样是不是很麻烦,能不能把这个check_Indication()放到类里面,并且让类的所有对象都能方便共享呢,有同学说简单,挪进来,然后再把调用check_Indication的地方变成Robot.check_Indication()


robot1 = Robot('No1_Machine')
robot1.do_Reset()
>>
TypeError: unbound method check_Indication() must be called 
with Robot instance as first argument (got nothing instead)


直接报错,根本不行,这个时候静态函数就可以派上用场了


robot1 = Robot('No1_Machine')
robot1.do_Reset()
robot1.save_DB()
robot2 = Robot('No2_Machine')
robot2.do_Reset()
robot2.save_DB()
>>
Reset done for :No1_Machine
DB connection ready for: No1_Machine
Reset done for :No2_Machine
DB connection ready for: No2_Machine
3.类方法

类的方法就叫类方法,当我们要写一个只在类中运行而不在实例中运行的方法. 
比如我们想让方法不在实例中运行,就可以用到类方法.也是用装饰器@classmethod来修饰的
举个例子我们有一个Student类,我们想记录有多少个学生
def get_num_of_instance(cls_obj):
return cls_obj.num_student
class Student(object):
num_student=0
def __init__(self):
Student.num_student+=1
s1=Student()
s2=Student()
total_num=get_num_of_instance(Student)
print total_num

>>
2

其实我完全可以在类里面建一个函数,然后获得类的引用去获取类的变量,这样不是很简单吗:

class Student(object):
num_student=0
def __init__(self):
Student.num_student+=1
@classmethod
def get_num_of_instance(cls):
return cls.num_student
s1=Student()
s2=Student()
total_num=s1.get_num_of_instance()
print total_num
>>
2
total_num=s2.get_num_of_instance()
print total_num
>>
2
total_num=Student.get_num_of_instance()
print total_num
>>
2

这样的好处是:

不管这个方式是从实例调用还是从类调用,它都用第一个参数把类传递过来.聪明的同学发现其实类方法的作用和静态函数很像,确实很像,接着往下看

4.类方法,静态函数,实例方法之间调用关系



1). 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制

2).实例方法可以访问实例属性和类属性,也可以访问静态方法和类方法.

3). 类方法可以被对象调用,也可以被实例调用;传入的都是类对象,主要用于工厂方法,具体的实现就交给子类处理

3). 静态方法参数没有实例参数 self, 也就不能调用实例参数,实例方法




好了Python中的类方法揭秘就讲到这里啦,希望能给初学者一些启发,若有什么不懂的,也可以留言跟我探讨交流.

最后说一下,原创真的不易,希望大家能够给点支持,欢迎转发转发转发,留言留言留言,重要的事情说三遍,也是对我的一点鼓励和动力.

也欢迎更多喜欢Python的同学关注 菜鸟学python,一起来学python吧 长按下方的二维码即可关注.


推荐 2
本文由 菜鸟学Python 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册