我的编程空间,编程开发者的网络收藏夹
学习永远不晚

使用python如何实现泛型函数

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

使用python如何实现泛型函数

python实现泛型函数

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型。 ——来自百度

简易理解

泛型函数就是你定义函数的时候, 能接收万能类型, 在调用时, 会根据传入值本身的类型进行区分处理, 达到某些效果, 好处是代码复用率高, 减少代码冗余, 对面向对象语言中泛型函数概念非常常用.

接下来使用到的py库 functools 中的 singledispatch 模块

使用方法

在需要进行泛型的函数上加上装饰器即可

from functools import singledispatch
@singledispatch
def add(obj):
    return obj
  • 1 singledispatch : 标记处理函数传值类型
  • 2 register(类型): 为传值判断类型后输出结果
  • 3 后续使用无需写函数名, 只要有register(类型装饰器)即可调用
  • 4 定义需要判断的类型int str tuple dict list set 根据自己需求

函数中实现类型判断

from functools import singledispatch
@singledispatch
def add(obj):
    return obj
int类型
@add.register(int)
def _(add):
    print("int类型")
@add.register(str)
def _(add):
    print("str类型")
    
@add.register(list)
def _(add):
    print("list类型")
    
@add.register(tuple)
def _(add):
    print("tuple类型")
    
@add.register(dict)
def _(add):
    print("dict类型")
    
@add.register(set)
def _(add):
    print("set类型")
    
add([1,2,3])  

输出结果: list类型

根据输入的内容进行判断类型输出

对象中使用

from functools import singledispatch
class Type:
    @singledispatch
    def add(obj):
        return obj
    @add.register(int)
    def _(add):
        print("int类型")
    @add.register(str)
    def _(add):
        print("str")
    @add.register(list)
    def _(add):
        print("list类型")
    @add.register(tuple)
    def _(add):
        print("tuple类型")
    @add.register(dict)
    def _(add):
        print("dict类型")
    @add.register(set)
    def _(add):
        print("set类型")
Type.add([1,2,3])

输出结果:list类型

不调用singledispatch模块实现泛型函数

这里需要实现一个类型拼接操作, 如下代码

在此之前需要先定义一个装饰器, 来判断两个类型是否相同, 如果不同则不作后续判断, 节省资源消耗

def check_type(func):
    def wrapper(*args, **kwargs):
        args1, args2 = args[:2]
        if type(args1) != type(args2):
            return "两种类型不一致, 不能做拼接"
        return func(*args, **kwargs)
    return wrapper
@check_type
def add(obj1, obj2):
    if isinstance(obj1,list):
        obj1 += obj2
        return obj1
    if isinstance(obj1, str):
        obj1 += obj2
        return obj1
    if isinstance(obj1, tuple):
        obj1 += obj2
        return obj1
    if isinstance(obj1, dict):
        obj1 += obj2
        return obj1
print(add([1, 2, 3], [1, 2, 3]))

结果与上方一样, 按需选择

例子很简单, 最后多用于tcp/ip接收判断使用

提示: bool类型也是可以的,完!

Python泛型思考

近日在学习Python内容时学习到了泛型,但从个人看法来说Python泛型与Java的泛型有很大的不同,在此提出一点个人的看法

首先,针对Java的泛型,其主要作用是作为某些以后才指定类型的替代,在编写过程中这些泛型可以在实例化过程中由参数指定,典型例子如集合类当中的泛型

List<String> list = new ArrayList<String>()

这就相当于指定了该集合类的新类型。泛型使用的原因是可以加强类型转化的安全性以及减少转换的次数。比如在上例中的List集合中,如果从中取出一个元素,在未指明泛型的前提下,取出的类型元素只能是Object,必须使用强制类型转换转化为对应的类型才能供后续代码使用。

那么,此处就可能存在问题,因为没有指明泛型,那么意味着加入集合的时候只要你的元素类型是Object即可加入,由于在Java中Object为最高基类,意味着任何元素都可加入泛型当中,由此,没有任何办法保证你取出的元素一定是你想要的的类型,所以此时为保证程序健壮性必须处理ClassCastException异常;但在指明泛型后,由于出入都可以限制元素类型,所以减少了此种转换的异常,也就保证了转换的安全性。

由以上描述可以知道,泛型首先要求的是你能够在实例化时指定类型,所以泛型一般应用于强类型的语言当中才比较好用,但Python本身是弱类型语言,所以Python的泛型并不完全是这种作用

Python的泛型类Generic的注释中提到,

A generic type is typically declared by inheriting from an instantiation of this class with one or more type variables.

也就是说,Python 的泛型类型是继承这个类之后才会声明,这种声明方式与Python的抽象类声明方式十分类似。以IO下的三个实现类为例,其声明分别为

class IO(Generic[AnyStr]):
class BinaryIO(IO[bytes]):
class TextIO(IO[str]):

从这些定义中可以看出,在声明泛型类之后IO类便可以使用泛型的方式去作为其他类的基类定义,

并且AnyStr在Python的类型声明中是包含了bytes与str两类的,由此我们可以发现Python的泛型与Java泛型的一个最根本区别:Python 的泛型是在声明时就指定了泛型类型,也就是说,Python的泛型类型主要作用是:某个类存在多种使用场景,并且我们可以预知各个使用场景的类型,为了将原始代码能够广泛应用于其他场景上使用泛型去保障代码在各个场景上的通用性。因此,在泛型类的声明中并不像其他语言一样使用类似T的方式去替代类型,而是直接使用已经声明的泛型类型在代码中书写,如readline函数的定义

    @abstractmethod
    def readline(self, limit: int = -1) -> AnyStr:
        pass

由此,我们可以归纳Python泛型的两个条件:

1.继承Generic类,并在类的参数中指明泛型类型

2.在实现中使用泛型类型参与代码编写

最后,由于在声明时就已经指定了泛型的类型,所以Python泛型更大程序上我认为是一个具有辅助说明的功能,相当于说明在编写当中告诉编程人员应当使用什么类型,这其实从另一个层面上也是在其他语言中泛型功能的一大体现 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

使用python如何实现泛型函数

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何使用 C++ 函数模板实现函数指针的泛型化?

c++++ 函数模板允许泛化函数指针,支持不同类型参数的函数指针。具体步骤如下:声明带有函数指针的函数模板,其中 t 为模板类型参数。将要泛化的函数指针作为参数传递给模板函数。模板函数返回泛型函数指针。使用 C++ 函数模板实现函数指针的泛
如何使用 C++ 函数模板实现函数指针的泛型化?
2024-04-15

如何利用 C++ 函数模板实现泛型编程?

泛型编程通过函数模板实现,允许创建通用的代码处理不同类型的数据,无需修改源代码。函数模板的基本语法为:template returntype functionname(t arg1, t arg2, ...),其中 t 为类型参数。通过实
如何利用 C++ 函数模板实现泛型编程?
2024-04-15

泛型函数在Golang中如何与现有的非泛型函数交互?

在 go 中,泛型函数可以通过使用类型断言、类型别名或空的接口与非泛型代码交互。类型断言允许将值转换为特定类型;类型别名可以创建现有类型的泛型别名;空的接口可以表示任何类型的变量。通过这些方法,泛型函数可以接受或返回非泛型类型的值,从而实现
泛型函数在Golang中如何与现有的非泛型函数交互?
2024-04-16

C++ 函数重载如何用于实现泛型编程?

函数重载允许创建具有相同名称但参数不同的函数,从而实现泛型编程。它允许我们编写代码来处理不同类型的参数,同时使用相同的函数名称。在实战中,我们可以使用重载函数对不同类型的数据进行求和,例如整数和浮点数。通过使用函数重载,我们可以提高代码的可
C++ 函数重载如何用于实现泛型编程?
2024-04-13

C++ 函数的泛型编程如何实现代码复用?

c++++ 中的泛型编程使用模板创建可处理任何类型的泛型函数。它提高了代码重用性,减少了错误。示例包括泛型比较函数,可用于比较任意两种类型对象。实战案例,例如排序算法,展示了泛型比较函数如何用于对不同类型数据进行排序。C++ 函数的泛型编程
C++ 函数的泛型编程如何实现代码复用?
2024-04-12

如何创建和使用 C++ 泛型函数指针?

泛型函数指针是一种 c++++ 中指向不同类型和参数数量函数的指针。创建泛型函数指针需要使用模板,其中指定函数的返回值类型和参数类型元组。可通过以下语法使用泛型函数指针:声明函数指针,将函数赋值给函数指针,调用通过函数指针指向的函数。实战案
如何创建和使用 C++ 泛型函数指针?
2024-04-17

java泛型如何实现

在Java中,泛型是通过使用尖括号来实现的。在类或方法的声明中,可以使用泛型来指定一个或多个类型参数。在类的声明中,可以在类名后面使用尖括号来指定一个或多个类型参数。例如,下面的代码是一个泛型类的声明:public class MyGe
2023-10-27

C++ 函数库如何使用模版和泛型编程?

c++++ 中的模版和泛型编程允许创建可重用的函数库,其特点包括:模版:参数化类型,在编译时创建类型。泛型编程:利用模版和类型推断编写适用于多种数据类型的代码。实战案例:可重用排序函数可用于任何可比较类型,例如 int 和字符串。C++ 函
C++ 函数库如何使用模版和泛型编程?
2024-04-19

Golang泛型如何使用

这篇文章主要介绍了Golang泛型如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang泛型如何使用文章都会有所收获,下面我们一起来看看吧。1. 泛型是什么泛型生命周期只在编译期,旨在为程序员生成代
2023-07-02

C#如何实现泛型类

这篇文章主要为大家展示了“C#如何实现泛型类”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#如何实现泛型类”这篇文章吧。使用泛型集合有些人问我"面向对象编程(OOP)的承诺在哪里?",我的回答
2023-06-17

如何使用 C++ 函数指针重载和泛型编程?

c++++ 函数指针重载通过指定不同函数签名实现指向具有相同名称但不同参数或返回值的多函数指针。泛型编程使用模板创建适用于不同类型数据的函数和数据结构,使代码可重用。使用函数指针重载需要为每种类型编写单独的函数,而泛型编程则使用通用函数处理
如何使用 C++ 函数指针重载和泛型编程?
2024-04-17

C++ 函数继承详解:如何使用模板继承来实现泛型代码复用?

c++++ 函数继承通过模板继承实现泛型代码复用,允许创建通用函数模板,然后继承更具体的函数,定制不同的数据类型行为。代码示例包括打印容器函数,通过继承定制打印整数和字符串容器。函数继承增强代码复用、可读性、可维护性,以及通过继承类轻松扩展
C++ 函数继承详解:如何使用模板继承来实现泛型代码复用?
2024-05-04

Golang泛型如何影响函数类型推断?

go泛型通过引入类型参数化改变了函数类型推断:参数类型:[]a,其中a是满足number接口的实际类型参数,在调用时具体化。返回值类型:与参数类型相同,推断为a。Go 泛型如何影响函数类型推断Go 语言中的泛型引入了一种新的类型推断机制,
Golang泛型如何影响函数类型推断?
2024-04-16

PHP如何使用函数实现类型转换

这篇文章主要介绍了PHP如何使用函数实现类型转换,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。转换函数转换通过intval() floatval() strval()三个转换
2023-06-17

如何使用 Golang 函数类型实现回调?

是的,在 go 中可以使用函数类型实现回调功能,具体步骤如下:声明一个函数类型,指定回调函数的签名。定义一个接受函数类型作为参数的函数。将需要回调的函数传递给该函数。使用 Golang 函数类型实现回调在 Go 中,函数类型允许您将函数声
如何使用 Golang 函数类型实现回调?
2024-04-22

TypeScript 泛型重载函数的使用方式

这篇文章主要介绍了TypeScript 泛型重载函数的使用方式,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
2022-11-13

Golang泛型如何扩展函数的可重用性?

go 泛型是一种特性,通过参数化类型,使代码可重用,包括:类型安全的集合:可创建存储不同类型元素的集合。通用的比较函数:可比较任何实现了 comparable 接口的类型。Go 泛型:扩展函数可重用性的利器简介在 Go 1.18 版本中
Golang泛型如何扩展函数的可重用性?
2024-04-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录