有时候我们会听到Python里所谓的鸭子类型和猴子补丁的说法,乍一听还以为是来到了动物园,Python这只大蟒蛇还可以和鸭子和猴子一起玩耍?
非也非也,鸭子类型和猴子补丁实际上是两个生动有趣的比喻,用来说明Python的动态特性。
鸭子类型🦆(duck type) 是对Python中数据类型本质上是由属性和行为来定义的一种解读。
猴子补丁🐒(monkey patching)是对Python中类和模块可以在外部被动态修改这种特性的一个比喻。
让我们来一探究竟吧!
一,鸭子类型
鸭子类型是对Python中数据类型本质上是由属性和行为来定义的一种解读。
Python是一种动态语言,不像Java和C++这种强类型语言,Python里实际上没有严格的类型检查。
只要某个对象具有鸭子的方法,可以像鸭子那样走路和嘎嘎叫,那么它就可以被其它函数当做鸭子一样调用。
#这是一个鸭子(Duck)类
classDuck:
def__init__(self,name):
self.name=name
defswim(self):
print("Aducknamed"+self.name+"isswimming...")
defcall(self):
print("gay...gay...gay...")
#这是一个鹅(Goose)类
classGoose:
def__init__(self,name):
self.name=name
defswim(self):
print("Agoosenamed"+self.name+"isswimming...")
defcall(self):
print("goo...goo...goo...")
# duckshow这个函数设计的本意是需要传入一个Duck对象作为参数的。
defduckshow(duck):
duck.swim()
duck.call()
yaya=Duck("yaya")
ee=Goose("ee")
#但由于Python是动态语言,其数据类型属于鸭子类型,没有严格类型检查,
#Goose这个类具有和Duck这个类相同的方法,
#ee这只鹅划起水来像只鸭子,叫起来也像一只鸭子,
#所以duckshow这个函数也可以对ee进行作用。
duckshow(yaya)
duckshow(ee)
输出结果如下:
A duck named yaya is swimming...gay ... gay ... gay ...A goose named ee is swimming...goo ... goo ... goo ...
二,猴子补丁
猴子补丁是对Python中模块和类可以在外部被动态修改这种特性的一个比喻。
为什么叫做猴子补丁呢?在模块和类的外部对模块和类进行修改是一种非常耍赖的做法,会破坏代码的封装结构,这种事情大概只有淘气的猴子喜欢去做,因此形象地称之为猴子补丁。
#定义一个Dog类
classDog:
def__init__(self,name,age):
self.name=name
self.age=age
defsleep(self):
print("Zzz...Zzz..Zzz...")
#在类的外部给Dog这个类添加猴子补丁
defspeak(self):
print("Ithinkmyselfaheroandveryhandsome!")
Dog.speak=speak
Dog.home="Earth"
#与类的内部定义的属性和方法无差异
snoopy=Dog("snoopy",3)
snoopy.sleep()
snoopy.speak()
print(snoopy.home)
输出结果如下:
Zzz...Zzz...Zzz...I think myself a hero and very handsome!Earth
对于库中已经定义好的类,给它们添加猴子补丁有时候会非常方便,相当于可以自由地在外面做扩展,又不用修改源文件。
importnumpyasnp
importpandasaspd
df=pd.DataFrame(np.random.randint(1,10,size=(5,5)),
columns=list("abcde"))
#df.info()
#DataFrame自带方法info打印信息太多,展示不直观。
#给DataFrame定义一个猴子补丁方法memory简洁展示其内存消耗。
defmemory(self):
mem=self.__sizeof__()
ifmem<1024:
return("%sB"%mem)
elifmem<1024*1024:
return("%sKB"%mem/1024)
elifmem<1024**3:
return("%sMB"%mem/1024**2)
else:
return("%sGB"%mem/1024**3)
pd.DataFrame.memory=memory
print(df.memory())
输出结果如下:
280 B
这就是Python里的鸭子类型和猴子补丁的一个简单介绍,你耍明白了吗?🐒🐒🐒🦆🦆🦆