本文主要介绍如何用python的鸭子类型的实现方式,用魔法函数来实现自定义类,想歪的同学快出去面壁思过,所需基础可参考本公众号之前的文章。
在python中,函数和类也是对象,属于python的一等公民。这些一等公民也就是对象具有以下几个特性: •可以赋值给一个变量
•可以添加到集合对象中
•可以作为参数传递给函数
•可以当做函数的返回值
静态语言中将类加载到内存中运行的时候,类是不可修改的,因为已经编译完成。python为动态语言,全面向对象编程:所有得类都是type的实例,除object来其他类都继承object类,都是可以修改的。
这里就不得不介绍鸭子类型,鸭子类型简单点来说,就是如果你具有鸭子的属性,那你就是鸭子。比如,鸭子会嘎嘎叫,鸭子会两只脚走路。那么你如果实现了这两个方法,那么就可以说这个类型是鸭子类。这一点和许多静态语言是相反的,静态语言往往是先定义一个实体,再去描述实体的属性和方法。鸭子类型的特性是根据魔法函数来实现的,决定了该class可以如何被使用。
实战:比如一个可迭代对象底层基于__iter__和__next__的调用,那么我们就可以定义一个类,类中有__iter__和__next__这两个方法,就说明这个类是可迭代对象。
魔法函数是python中的特殊方法,那你可以理解为,这些特殊方法是一些定义好的回调行为, 所以魔法函数不能自定义,定义之后不需要调用,若你将这些行为用到自己的类中,那么当触发这个回调后就会调用这个方法,语法规则为双下划线加方法名称。如__{FUNC}__。
•默认情况下(也即用户不显式写出__repr__方法时)会得到“类名+object at+内存地址”这样格式的信息•当显示写出__repr__方法时,解释器会按照你所定义的格式输出实例对象信息
•__repr__面向程序员
•当使用print输出对象的时候,若定义了__str__(self)方法,打印对象时就会从调用这个方法并 打印出return的字符串数据•__str__面向用户
•__repr__适用于所有环境中,__str__只是覆盖了__repr__以得到更友好的用户显示
栗子:
class Test:
def __str__():
return "test"
def __repr__():
return "TEST_CLASS"
a = Test()
print(a)
输出:
test
tips: python内置类型(int list dict)底层均为c语言写的, 需要用cython解释器去执行,所以长度在一开始分配内存空间的时候就已经确定了,而不是去遍历,所以用魔法函数的len的效率高
栗子:
class WordNums():
def __init__(self, *args):
self.word = args
def __len__(self):
print("调用了__len__方法")
return len(self.word)
ret = WordNums('hello', 'world', 'Python', 'encoding')
print(len(ret))
输出:
调用了__len__方法
4
•上文中提到了魔法函数有些并不是很常用,了解即可,推荐根据功能进行学习而不是根据特定的方法。•🚀 不定时分享干货,有兴趣的可以关注我公众号。