你知道什么是Python里的鸭子类型和猴子补丁吗?

640?wx_fmt=jpeg


作者 |  梁云1991

来源 | Python与算法之美(ID:Python_Ai_Road)


有时候我们会听到Python里所谓的鸭子类型和猴子补丁的说法,乍一听还以为是来到了动物园,Python这只大蟒蛇还可以和鸭子和猴子一起玩耍?u1F604.pngu1F604.pngu1F604.png

非也非也,鸭子类型和猴子补丁实际上是两个生动有趣的比喻,用来说明Python的动态特性。

鸭子类型?(duck type) 是对Python中数据类型本质上是由属性和行为来定义的一种解读。

猴子补丁?(monkey patching)是对Python中类和模块可以在外部被动态修改这种特性的一个比喻。

让我们来一探究竟吧!

一、鸭子类型


鸭子类型是对Python中数据类型本质上是由属性和行为来定义的一种解读。

Python是一种动态语言,不像Java和C++这种强类型语言,Python里实际上没有严格的类型检查。

只要某个对象具有鸭子的方法,可以像鸭子那样走路和嘎嘎叫,那么它就可以被其它函数当做鸭子一样调用。

# 这是一个鸭子(Duck)类	
class Duck:	
    def __init__(self,name):	
        self.name = name	
    def swim(self):	
        print("A duck named " + self.name+" is swimming...")	
    def call(self):	
        print("gay...gay...gay...")	

	
# 这是一个鹅(Goose)类	
class Goose:	
    def __init__(self,name):	
        self.name = name	
    def swim(self):	
        print("A goose named " + self.name+" is swimming...")	
    def call(self):	
        print("goo...goo...goo...")	

	
# duckshow这个函数设计的本意是需要传入一个Duck对象作为参数的。	
def duckshow(duck):	
    duck.swim()	
    duck.call()	

	
yaya = Duck("yaya")	
ee = Goose("ee")	

	
# 但由于Python是动态语言,其数据类型属于鸭子类型,没有严格类型检查,	
# Goose这个类具有和Duck这个类相同的方法,	
# ee这只鹅划起水来像只鸭子,叫起来也像一只鸭子,	
# 所以duckshow这个函数也可以对ee进行作用。	

	
duckshow(yaya)	
duckshow(ee)	

输出结果如下:

 
 
 
 

二、猴子补


猴子补丁是对Python中模块和类可以在外部被动态修改这种特性的一个比喻。

为什么叫做猴子补丁呢?在模块和类的外部对模块和类进行修改是一种非常耍赖的做法,会破坏代码的封装结构,这种事情大概只有淘气的猴子喜欢去做,因此形象地称之为猴子补丁。

# 定义一个Dog类	
class Dog:	
    def __init__(self,name,age):	
        self.name = name	
        self.age = age	

	
    def sleep(self):	
        print("Zzz...Zzz..Zzz...")	

	
# 在类的外部给Dog这个类添加猴子补丁	
def speak(self):	
    print("I think myself a hero and very handsome!")	

	
Dog.speak = speak	
Dog.home = "Earth"	

	
# 与类的内部定义的属性和方法无差异	
snoopy = Dog("snoopy",3)	
snoopy.sleep()	
snoopy.speak()	
print(snoopy.home)	

	

输出结果如下:

br

对于库中已经定义好的类,给它们添加猴子补丁有时候会非常方便,相当于可以自由地在外面做扩展,又不用修改源文件。

import numpy as np	
import pandas as pd	

	
df = pd.DataFrame(np.random.randint(1,10,size=(5,5)),	
                  columns = list("abcde"))	
#df.info()	
#DataFrame自带方法info打印信息太多,展示不直观。	
#给DataFrame定义一个猴子补丁方法memory简洁展示其内存消耗。	

	
def memory(self):	
    mem = self.__sizeof__()	
    if mem<1024:	
        return("%s B"%mem)	
    elif mem<1024*1024:	
        return("%s KB"%mem/1024)	
    elif mem<1024**3:	
        return("%s MB"%mem/1024**2)	
    else:	
        return("%s GB"%mem/1024**3)	

	
pd.DataFrame.memory = memory	

	
print(df.memory())

输出结果如下:

280 B	
br

这就是Python里的鸭子类型和猴子补丁的一个简单介绍,你耍明白了吗???????

640?wx_fmt=png

推荐阅读


640?wx_fmt=png

你点的每个“在看”,我都认真当成了喜欢

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值