新版博客SEO优化基本完成,新老博客内容正在整合中,保证每篇文章高质量。 SiteMap RSS Github
Python鸭子类型和猴子补丁
嘉美伯爵   2019年6月5日 21:01   Python   语法   155  

鸭子类型

魔术方法与鸭子类型

只要你实现了iter____next__魔术方法,你就可以实现一个range()函数

from collections.abc import Iterator
class Foo:

    def __init__(self, num):
        self.num = num
        self.data = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.data > self.num:
            raise StopIteration
        self.data += 1
        return self.data - 1


foo = Foo(3)

for item in foo:
    print(item) # 0, 1, 2, 3

print(isinstance(foo, Iterator)) # True

继承与鸭子类型

在介绍鸭子类型之前我们介绍一下Java的工厂设计模式,即我想吃一个水果,我并关心这个苹果是怎么形成的,即我想吃苹果你就让我吃苹果,我想吃香蕉,你就让我吃香蕉,在我们分析下面的代码可以知道我们可以把相同的行为抽取出来,在Java中要实现这一行为必须要用接口实现,而Python中则是你具有这个功能,我就可以执行你,这也是Python不用设计那么多设计模式的原因。现在我们可以回归那一句经典的话“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

  • Java 工厂设计模式
interface Fruits{
    public void eat();
}
class Oranger implements Fruits{
    public void eat(){
        System.out.println("Eat Orange");
    }
}
class Apple implements Fruits{
    public void eat(){
        System.out.println("Eat Apple");
    }
}
class Factory{
    public static Fruits getIstance(String name){
        if("Apple".equals(name)){
            return new Apple();
        }else if("Oranger".equals(name)){
            return new Oranger();
        }else{
            return null;
        }
    }
}
public class Duo{
    public static void main(String []args){
        Fruits f = Factory.getIstance("Apple");
        f.eat();
    }
}
  • Python 鸭子类型
# -*- coding: utf-8 -*-

class Duck:
    def walk(self):
        print("I can walk")

    def swimming(self):
        print("I can swimming")


class BlackDuck(Duck):
    def swimming(self):
        print("black duck can swimming")


class Person:
    def walk(self):
        print("All person can walk")

    def swimming(self):
        print("em~ i'm not a real duck")

def duck_game(duck):
    duck.swimming()
    duck.walk()

if __name__ == '__main__':
    duck = Duck()
    black = BlackDuck()
    person = Person()

    duck_game(duck)
    duck_game(black)
    duck_game(person)

Python3.6 新加类型说明

在Python3.6之前,函数或变量的数据类型是程序员写在注释中的,Python3.6新加了下面的类型说明,程序员可以减少一定的文档说明,但你应该注意的是它只是一个说明,并不像java一样又严格的类型要求,即使你把下面的返回类型str改名int也不会报错,真实的数据类型还是根据Python解释器运行时确定,他只是一种代码规范。

def print_name(name: str) -> str
    print("I'm is {}.".format(name))

print('Gage')

猴子补丁

猴子补丁指的是你可以在代码运行期间给你的程序动态的添加属性或方法,比如你的团队想丰富模块的功能,除了继承之外也可以考虑用Monkey Patch

from SomeOtherProduct.SomeModule import SomeClass

def speak(self):
    return "ook ook eee eee eee!"

SomeClass.speak = speak

参考文档

What is monkey patching?

python与鸭子类型

什么是鸭子类型(duck typing)

Python:动态语言与鸭子类型