【Python】到底什么是鸭子类型?(python有什么用处)

admin|
133


只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子\\ 只保藏不点赞的都不是好孩子\\ 只保藏不点赞的都不是好孩子

1. 举一个例子

我们起首以静态语言Java为例,来停止申明。在以下例子中,有Duck和Frog两个类,而inTheForest函数的参数必需是Duck类型,一旦输入Frog类型的参数就会报错。因为静态语言对类型有着严酷的限造,而Duck类型的实例无法转型为Frog。

所以,虽然Frog类型同样也有quack()和walk()两个函数,看起来似乎满足inTheForest函数的要求,但现实上却无法运行。

class Duck {        public void quack() {        System.out.println("嘎嘎嘎!");        }        public void walk() {        System.out.println("摇摇摆晃!");        }        }        class Frog {        public void quack() {        System.out.println("呱呱呱!");        }        public void walk() {        System.out.println("跳啊跳!");        }        }        public class MyClass {        public static void inTheForest(Duck duck) {        duck.quack();        duck.walk();        }        public static void main(String[] args) {        Duck d = new Duck();        MyClass.inTheForest(d);        Frog f = new Frog();        // 毫无疑问,那里会报错,因为Frog类型的实例f不克不及转型为Duck         MyClass.inTheForest(f);        }        }

而在Python中则完全不存在那种问题:因为f也有quack和walk两个办法,因而放入in_the_forest函数中完全不会报错。那种机造,就称为鸭子机造(Duck Typing):即f固然是Frog类,但是只要它能够quack和walk,那它就能够当做Duck用在in_the_forest函数里面。

class Duck():        def quack(self):        print("嘎嘎嘎!")        def walk(self):        print("摇摇摆晃!")        class Frog():        def quack(self):        print("嘎嘎嘎!")        def walk(self):        print("摇摇摆晃!")        def in_the_forest(obj):        obj.quack()        obj.walk()        d = Duck()        in_the_forest(d)        # 因为f也有quack和walk两个办法,因而放入in_the_forest函数中完全不会报错        # 那种机造就称为鸭子类型        f = Frog()        in_the_forest(f)

那么Java中若何处理那一问题呢?一个法子就是为Duck和Frog写一个配合的父类Animal,把inTheForest函数的参数改为Animal类型,如下所示。在那种办法中,Duck和Frog称为父类Animal的差别形态,因而鸭子类型也是多态的一种呈现。此外,也能够用接口并把inTheForest函数改成泛型函数,更多办法能够拜见Java中实现鸭子类型机造。

class Animal {        public void quack() {        System.out.println("叫!");        }        public void walk() {        System.out.println("行走!");        }        }        class Duck extends Animal {        public void quack() {        System.out.println("嘎嘎嘎!");        }        public void walk() {        System.out.println("摇摇摆晃!");        }        }        class Frog extends Animal {        public void quack() {        System.out.println("呱呱呱!");        }        public void walk() {        System.out.println("跳啊跳!");        }        }        public class MyClass {        public static void inTheForest(Animal animal) {        animal.quack();        animal.walk();        }        public static void main(String[] args) {        Duck d = new Duck();        MyClass.inTheForest(d);        Frog f = new Frog();        MyClass.inTheForest(f);        }        }        2. Python中鸭子类型的更多应用

鸭子类型在Python中有着普遍应用,如:

但凡内置了__contains__办法的类型都能够认为是Container类;但凡内置了__iter__办法的类型都能够认为是Iterable类;但凡内置了__call__办法的类型都能够认为是Callable类。

类似的还要良多,详见容器的笼统基类。

以Iterable为例,tuple, list, set, dict均内置了__iter__函数,因而都可用于for轮回,因而均能够用于下面的print_one_by_one函数中。

from typing import Iterable        def print_one_by_one(it: Iterable):        for e in it:        print(e)        print_one_by_one((1, 2, 3)) # tuple        print_one_by_one([1, 2, 3]) # list        print_one_by_one({1, 2, 3}) # set        print_one_by_one({"a": 1, "b": 2, "c": 3}) # dict

只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子只保藏不点赞的都不是好孩子\\ 只保藏不点赞的都不是好孩子\\ 只保藏不点赞的都不是好孩子