python鸭子模型,python鸭子模式

  python鸭子模型,python鸭子模式

  不知不觉用python写代码已经很久了。下面这篇文章主要介绍python ducktype和mokeypatching的相关信息,通过示例代码非常详细的介绍。有需要的可以参考一下。

  00-1010鸭式猴贴前言摘要

  

目录

  Python开发者可能都听过鸭式和猴式补丁这两个词。就算没有,他们大概也写过相关代码,只是不知道背后的技术点就是这两个字。

  我最近面试考生的时候也问过这两个概念,很多人回答的都不是很好。但我跟他们解释的时候,一般都是恍然大悟:“哦,是这个,我用的”。

  所以,我决定写一篇文章来讨论这两种技术。

  

前言

  引用维基百科的解释:

  鸭式类型是编程中动态类型的一种风格。在这种风格中,对象的有效语义不是通过从特定类继承或实现特定接口来确定的,而是通过“当前方法和属性的集合”来确定的。

  更通俗地说:

  当一只鸟像鸭子一样走路,像鸭子一样游泳,像鸭子一样叫的时候,它就可以被称为鸭子。

  也就是说,在鸭子类型中,重点是对象的行为和它能做什么;而不是相关对象的类型。

  让我们看一个例子来更形象地展示它:

  #这是一堂鸭子课。

  鸭子:级

  def eat(自身):

  打印(一只鸭子在吃…)

  def walk(self):

  打印(一只鸭子在走.)

  #这是一堂狗课。

  Dog:类

  def eat(自身):

  print(一只狗在吃…)

  def walk(self):

  print(一只狗在走.)

  动物定义(对象):

  吃

  行走

  if __name__==__main__:

  动物(鸭子())

  动物(狗())

  程序输出:

  一只鸭子正在吃东西.

  一只鸭子正在走路.

  一只狗正在吃东西.

  一只狗正在散步.

  Python是一种没有严格类型检查的动态语言。只要鸭和狗分别实现吃和走的方法,就可以直接调用。

  比如list.extend()方法,除了list,dict,tuple也可以调用,只要是迭代的。

  看了上面的例子,你应该对“对象的行为”和“对象所属的类型”有了更深的理解。

  再多一点,其实duck type和interface差不多,只不过没有显式定义接口。

  比如用Go语言实现duck类型,代码是这样的:

  主包装

  导入 fmt

  //定义接口,包括Eat方法

  Duck接口类型{

  吃()

  }

  //定义Cat结构并实现Eat方法

  卡特彼勒结构类型{}

  func (c *Cat) Eat() {

  fmt。Println(“猫吃”)

  }

  //定义Dog结构并实现Eat方法

  键入Dog结构{}

  func (d *Dog) Eat() {

  fmt。Println(“吃狗肉”)

  }

  func main() {

  var c Duck=Cat{}

  c.吃()

  var d Duck=Dog{}

  d.吃()

  s :=[]鸭子{

  猫{},

  狗{},

  }

  for _,n :=范围s {

  名词(noun的缩写)吃()

  }

  }

  通过显式定义Duck接口,每个结构都实现了接口中的方法。

  

鸭子类型

  

  猴子补丁(Monkey Patch)的名声不太好,因为它会在运行时动态修改模块、类或函数,通常是添加功能或修正缺陷。

  猴子补丁在内存中发挥作用,不会修改源码,因此只对当前运行的程序实例有效。

  但如果滥用的话,会导致系统难以理解和维护。

  主要有两个问题:

  

  • 补丁会破坏封装,通常与目标紧密耦合,因此很脆弱
  • 打了补丁的两个库可能相互牵绊,因为第二个库可能会撤销第一个库的补丁

  所以,它被视为临时的变通方案,不是集成代码的推荐方式。

  按照惯例,还是举个例子来说明:

  

# 定义一个Dog类

  class Dog:

      def eat(self):

          print("A dog is eating ...")

  # 在类的外部给 Dog 类添加猴子补丁

  def walk(self):

      print("A dog is walking ...")

  Dog.walk = walk

  # 调用方式与类的内部定义的属性和方法一样

  dog = Dog()

  dog.eat()

  dog.walk()

  程序输出:

  

A dog is eating ...
A dog is walking ...

  

  这里相当于在类的外部给 Dog 类增加了一个 walk 方法,而调用方式与类的内部定义的属性和方法一样。

  再举一个比较实用的例子,比如我们常用的 json 标准库,如果说想用性能更高的 ujson 代替的话,那势必需要将每个文件的引入:

  

import json

  

  改成:

  

import ujson as json

  

  如果这样改起来成本就比较高了。这个时候就可以考虑使用猴子补丁,只需要在程序入口加上:

  

import json  

  import ujson  

  def monkey_patch_json():  

      json.__name__ = ujson  

      json.dumps = ujson.dumps  

      json.loads = ujson.loads  

  monkey_patch_json()

  这样在以后调用 dumps 和 loads 方法的时候就是调用的 ujson 包,还是很方便的。

  但猴子补丁就是一把双刃剑,问题也在上文中提到了,看需,谨慎使用吧。

  

  

总结

  到此这篇关于Python中鸭子类型和猴子补丁的文章就介绍到这了,更多相关Python鸭子类型和猴子补丁内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: