使用type在对象方法中调用类方法
type简介
type在Python中的作用是创建一个类。
我们创建类的时候一般会使用这样的方法:
# -*- coding:utf-8 -*- class Student(object): country = "China" def add(self,x:int,y:int)->int: return x+y s1 = Student() print(s1.country) print(s1.add(12,23))
当然也可以使用type方法创建类,效果与上面的方法一样:
# -*- coding:utf-8 -*- Student = type( "Student", # 元组只有单个元素后面需要加逗号! (object,), { 'country':"China", 'add':lambda self,x,y:x+y } ) s1 = Student() print(s1.country) print(s1.add(12,33))
不过,我最近看公司某个封装好的功能的源码的时候,发现了它另外的一个用途,就是“在对象方法中调用类方法”(什么,你分不清对象方法、类方法与静态方法?请自行Google)。
在对象方法中使用类方法
基本操作
假设我们现在有一个Student类,要在对象方法中调用类方法,可以这样写:
# -*- coding:utf-8 -*- class Student(object): @classmethod def get_country(cls): return "China" def __init__(self,name): self.name = name # type(self),在对象方法中使用类的方法 self.country = type(self).get_country() def get_my_country(self): # type(self),在对象方法中使用类的方法 return type(self).get_country() if __name__ == '__main__': s1 = Student('wanghw') print(s1.country) # China print(s1.get_my_country()) # China # 事实上,对象也可以直接调用“类方法”,但是为了“规范”,我们不这么直接让对象直接调用“类方法” print(s1.get_country()) # China
起一个与类方法同名的对象方法再试试
上面的基本操作也许大家都明白,现在我们试一下极端的方式:起一个与类方法同名的对象方法,看看效果如何:
# -*- coding:utf-8 -*- class Student(object): @classmethod def get_country(cls): return "China" def __init__(self,name): self.name = name # type(self),在对象方法中使用类的方法 self.country = type(self).get_country() def get_my_country(self): # type(self),在对象方法中使用类的方法 return type(self).get_country() # 起一个与类方法同名的对象方法 def get_country(self): return "English" if __name__ == '__main__': s1 = Student('wanghw') print(s1.country) print(s1.get_my_country())
运行程序,你会发现上报了一个这样的错误:
TypeError: get_country() missing 1 required positional argument: 'self'
实际上,此时我们实例化的Student对象用的是自己的方法!而上面的__init__初始化方法与get_my_country方法的调用者是类Student,缺少了参数self,我们把程序修改如下(在get_country中加上参数self再试试):
# -*- coding:utf-8 -*- class Student(object): @classmethod def get_country(cls): return "China" def __init__(self,name): self.name = name # type(self),在对象方法中使用类的方法 self.country = type(self).get_country(self) def get_my_country(self): # type(self),在对象方法中使用类的方法 return type(self).get_country(self) # 起一个与类方法同名的对象方法 def get_country(self): return "English" if __name__ == '__main__': s1 = Student('wanghw') print(s1.country) # English print(s1.get_my_country()) # English
由此,我们可以得出结论:如果对象方法与类方法同名的话,对象会优先调用自己的方法!
其他相关的知识点详见这篇博客
其他关于type的说明,我自己之前总结过一篇关于type与isinstance的区别的文章,还有我在网上找的一篇很不错的关于type的说明的文章: