人人都能看懂的 Python 装饰器入门教程!

5分钟搞定微服务架构图:手把手教你用Draw.io画出专业级设计 本文详细介绍了如何使用Draw.io快速绘制专业级微服务架构图。通过5分钟入门教程,掌握核心组件拖拽、连接线优化等技巧,提升系统设计可视化效率。特别适合需要快速呈现分布式系统架构的开发团队,利用内置微服务元素和分层展示功能,轻松创建清晰易懂的技术文档。 阅读详情

大家好,我是菜鸟哥!

之前的文章中提到,很多人认为理解了装饰器 的概念和用法后,会觉得自己的 Python 水平有一个明显的提高。

但很多教程在一上来就会给出装饰器的定义以及基本用法,例如你一定会在很多文章中看到例如代码运行时间计时器等相关常用装饰器。

直接从应用入手这样学习当然十分有效,但不是看过就忘就是似懂非懂的状态,因为装饰器从来就不是一个单独的概念,就像数学分析中求积分一样,你可以通过公式快速算出需要求的积分,但是若明白积分是由极限定义的,之后再看积分将会是不一样的视角。

本文我将尝试说清楚为什么需要现装饰器、什么是装饰器、以及如何写一个简单的装饰器,但要彻底理解装饰器还要从函数开始说起,下面是有关函数的四个重要的概念,希望大家可以明白。

01

有关函数的四个重要概念

相信你在大多数文章中,至少也能知道例如「装饰器是装饰函数」,「在不修改函数代码的情况下增加额外功能」等核心概念,但首先要知道为什么函数能够被装饰。

例如在《流畅的Python》一书中,讲到函数的一开始就提出了一个概念,函数是一等对象

正如书中所说,在Python中一个函数既可以作为参数被传递,也能作为另一个函数的返回值,这也是函数可以被装饰的关键,在介绍装饰器之前,下面有必要通过简单的代码对这段话做一个更直观的理解。

1.1 函数中传递函数

函数中传递函数意思就是可以将函数当作变量来使用,我们来看一个简单的示例。

在下面的代码中,func1是一个普通的函数,接受两个参数a,b并返回他们的和。func2不一样的地方在于多接收了一个func参数,这个func变量需要是一个函数

def func1(a,b):
    
    print(f"函数 {func1.__name__} 正在执行")
    
    return a + b
    
def func2(func,c,d):
    
    print(f"函数 {func2.__name__} 正在执行")
    
    return func(c,d)

现在让我们来执行func1

>>> func1(1,2)
函数 func1 正在执行
3

下面func1作为参数执行func2

>>> func2(func1,3,4)
函数 func2 正在执行
函数 func1 正在执行
7

可以看到,先执行func2,在func2接收到fun1后,再次执行func1并返回。注意这里的func1没有括号,它只不过是和a,b一样的参数被使用,理解这点后我们继续看下一个知识点。

1.2 函数中定义函数

在定义一个函数后,可以继续在函数内部定义新的函数。为了理解这点,我们来看下面简单的示例。

我们先定义了一个函数func1,并在func1中定义了func2,并在func1的内部调用了func2

def func1():
    
    print(f"函数 {func1.__name__} 正在执行")

    def func2():
        
        print(f"内部函数 {func2.__name__} 正在执行")
        
    func2()

现在执行func1与func2看看会发生什么

>>> func1()
函数 func1 正在执行
内部函数 func2 正在执行

>>> func2()
------------------------------------------------
Traceback (most recent call last)

----> 1 func2()

NameError: name 'func2' is not defined

可以看到,当执行func1时,会自动执行func2,但是如果单独执行func2,则提示未定义,说明func2只能在func1中被调用!

1.3 函数返回函数

最后是一个函数可以将另一个函数作为返回值返回的简单示例,在下面的代码中,我们先定义了一个外部函数func1(接受一个参数a),之后定义了一个内部函数func2(接受一个参数b)并返回a + b,最后将func2作为func1的返回值返回

def func1(a):
    
    print(f"函数 {func1.__name__} 正在执行")
    
    def func2(b):
        
        print(f"函数 {func2.__name__} 正在执行")
        
        return a + b
    
    return func2

需要注意的是,这里返回的func2没有括号,代表返回的是func2的地址!

>>> func3 = func1(1)
>>> func3
函数 func1 正在执行
<function __main__.func1.<locals>.func2(b)>

>>> func3(2)
函数 func2 正在执行
3

从上面的运行结果可以看到,当执行func1(1)后,返回的是func2的地址,并赋给func3,之后执行func3(2)才真正执行了内部函数func2!

现在我们就解决了上一小节的问题「将内部函数func2单独拿出来用」!

1.4 函数内省

函数内省是相对来说比较好理解的一个概念,在Python中的意思就是我们可以访问函数的部分属性,例如print函数,可以使用dir函数来查看其全部属性

>>> dir(print)
['__call__',
 '__class__',
 '__delattr__',

  ··· ···

 '__subclasshook__',
 '__text_signature__']

现在可以查看其对应的属性

>>> print.__name__
'print'
>>> print.__call__
<method-wrapper '__call__' of builtin_function_or_method object at 0x7fddb8056b80>
>>> print.__doc__
"print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n\nPrints the values to a stream, or to sys.stdout by default.\nOptional keyword arguments:\nfile:  a file-like object (stream); defaults to the current sys.stdout.\nsep:   string inserted between values, default a space.\nend:   string appended after the last value, default a newline.\nflush: whether to forcibly flush the stream."

函数内省了解到这个程度即可,我们会在2.3节再次提到这里的知识!

至此,我已经将接触装饰器之前必须要吃透的知识点介绍完毕,如果你觉得我讲解的不够清晰,可以查看任何其他教程或者书籍弄懂后再继续阅读。

02

初识装饰器

现在终于可以来说说装饰器了,当然绝对不是直接告诉你一个写好的装饰器,而是我们一点一点去写一个简单的装饰器。

2.1 第一个装饰器

在下面的代码中,我们先定义了一个函数first_decorator,该函数接受函数为参数(如果不理解请查看本文 1.1 节),之后在内部定义了一个名为name_wrapper的内部函数(如果不理解请查看本文 1.2 节),最后返回以name_wrapper作为返回值(如果不理解请查看本文 1.3 节)

def first_decorator(func):
    def name_wrapper():
        
        print(f"被装饰的函数 {func.__name__} 即将执行")
        func()
        print(f"被装饰的函数 {func.__name__} 执行完毕")
        
    return name_wrapper

这个函数的功能是,在执行被接收函数前后分别打印一段话,所以我们要再定义一个函数来测试效果

def add():
    
    print("函数 add 正在执行 ")

这个fun1没有什么好说的,打印一段话。下面需要仔细看了,我们来执行这两段代码

>>> add = first_decorator(add)
>>> add()
被装饰的函数 add 即将执行
函数 add 正在执行 
被装饰的函数 add 执行完毕

正如我们预料的一样,在执行add前后都有一段提示,但是如果每次使用first_decorator功能都需要先将add传递,之后再调用,来回写好几遍,实在太麻烦了!

因此这完全有更Pythonic的写法,也就是我们常见的装饰器形式,使用语法糖@,例如上面的例子和下面的写法等价

@first_decorator
def add():
    
    print("函数 add 正在执行 ")

用@+装饰器函数名字放在需要被装饰函数的上方即可,现在直接调用add即可实现装饰器的功能!

>>> add()
被装饰的函数 add 即将执行
函数 add 正在执行 
被装饰的函数 add 执行完毕

相信看到这里,你应该明白装饰器@如何工作的,至少你在未来看到@时需要想到类似等价于add = first_decorator(add)一样的作用!

2.2 装饰器传参

上面仅是最简单的装饰器示例,在实际使用时

很自然的想法那就是加上参数呗,改起来也不难

@first_decorator
def add(x,y):
    
    
    print("函数 add 正在执行 ")
    print(f"{x} + {y} 的结果为{x+y}")

让我们来测试一下

>>> add(1,2)
-----------------------------------------------
Traceback (most recent call last)
<ipython-input-144-944f4051a32c> in <module>
----> 1 add(1,2)

TypeError: name_wrapper() takes 0 positional arguments but 2 were given

不出意外的报错了,虽然我们给被装饰的函数加上了参数,但是在装饰器的内部函数name_wrapper()执行时并没有参数!

因此我们之前的代码可以这么改,使用*args, **kwargs也是非常常见的用法

def first_decorator(func):
    def name_wrapper(*args, **kwargs):
        
        print(f"被装饰的函数 {func.__name__} 即将执行")
        func(*args, **kwargs)
        print(f"被装饰的函数 {func.__name__} 执行完毕")
        
    return name_wrapper

现在我们再次使用这个装饰器即可返回我们预测的结果!

@first_decorator
def add(x,y):
    
    print("函数 add 正在执行 ")
    print(f"{x} + {y} 的结果为 {x+y}")

>>> add(1,2)
被装饰的函数 add 即将执行
函数 add 正在执行 
1 + 2 的结果为 3
被装饰的函数 add 执行完毕

03

functools

本文的最后,还需要简单介绍一下在写装饰器时常用的functools模块。

还记得1.4节的函数内省相关知识吗?我们可以打印一个函数指向的内存地址或者名字等其他属性。

还是上面用到的add函数,我们都知道虽然被装饰了,但是功能上没有任何变化,依旧是计算两个数字的和,但是真的没有任何变化吗?下面让我们来观察一下

def add(x,y):
    
    print("函数 add 正在执行 ")
    print(f"{x} + {y} 的结果为{x+y}")
    
>>> print(add)
<function add at 0x7fddb9dd41f0>
>>>print(add.__name__)
add


@first_decorator
def add(x,y):

    print("函数 add 正在执行 ")
    print(f"{x} + {y} 的结果为{x+y}")
    
>>> print(add)
<function first_decorator.<locals>.name_wrapper at 0x7fddb9dd4e50>
>>> print(add.__name__)
name_wrapper

可以看到,被装饰后,虽然功能上没有变化,但是它指向的是装饰器所定义的内部函数!这并不是我们希望看到的,比如若不同函数被两个装饰器装饰时则会出现一样的函数名!

幸运的是Python中的functools库可以轻松解决这个问题,只需要加上一行简单的代码就可以搞定!

import functools


def first_decorator(func):
    @functools.wraps(func)
    def name_wrapper(*args, **kwargs):
        
        print(f"被装饰的函数 {func.__name__} 即将执行")
        func(*args, **kwargs)
        print(f"被装饰的函数 {func.__name__} 执行完毕")
        
    return name_wrapper

@first_decorator
def add(x,y):
    
    
    print("函数 add 正在执行 ")
    print(f"{x} + {y} 的结果为{x+y}")
    
>>> print(add)
<function add at 0x7fddb9dd4e50>
>>> print(add.__name__)
add

可以看到此时函数名等函数属性均保留下来了,事实上@functools.wraps(func)通过functools.update_wrapper()将原函数中的部分内省属性固定,只传递部分关键参数来实现这个功能,感兴趣的读者可以自行进一步研究。

至此,我想你应该明白为什么需要现装饰器、什么是装饰器、以及如何写一个简单的装饰器,当你再次看到装饰器时,脑海中浮现的概念应该不仅仅是@。有关装饰器更高级的用法,以及一些常见、好用的装饰器,我将在装饰器的第二篇文章中进行介绍!

左手Python,右手Java,升职就业不愁啦!

推荐阅读:入门: 最全的零基础学Python的问题  | 零基础学了8个月的Python  | 实战项目 |学Python就是这条捷径干货:爬取豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析 |   从万众期待到口碑扑街!唐探3令人失望  | 笑看新倚天屠龙记 | 灯谜答题王 |用Python做个海量小姐姐素描图 |碟中谍这么火,我用机器学习做个迷你推荐系统电影趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python《天天酷跑》游戏!AI: 会做诗的机器人 | 给图片上色 | 预测收入 | 碟中谍这么火,我用机器学习做个迷你推荐系统电影小工具: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保存为pdf!|  再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一款钉钉低价机票提示器! |60行代码做了一个语音壁纸切换器天天看小姐姐!|年度爆款文案1).卧槽!Pdf转Word用Python轻松搞定!2).学Python真香!我用100行代码做了个网站,帮人PS旅行图片,赚个鸡腿吃3).首播过亿,火爆全网,我分析了《乘风破浪的姐姐》,发现了这些秘密 4).80行代码!用Python做一个哆来A梦分身 5).你必须掌握的20个python代码,短小精悍,用处无穷 6).30个Python奇淫技巧集 7).我总结的80页《菜鸟学Python精选干货.pdf》,都是干货 8).再见Python!我要学Go了!2500字深度分析!9).发现一个舔狗福利!这个Python爬虫神器太爽了,自动下载妹子图片点阅读原文,领AI全套资料
实战干货|.NET9 C#上位机:多PLC并发通信+数据防丢+指令精准下发(10台设备实测+踩坑实录) 摘要:本文介绍了一个基于.NET9重构汽车零部件产线10台西门子S7-1200 PLC并发通信的工业级解决方案。针对原有系统存在的同步轮询阻塞、数据丢失、指令重复等问题,采用连接池复用、异步并发控制、超时隔离等技术,实现800ms内完成10台PLC并发采集、零丢包率、100%指令精准下发。方案通过.NET9的ThreadPool调度优化和ValueTask内存管理,将CPU占用控制在15%以内,解决了多PLC通信中的并发冲突、超时扩散等核心痛点,并提供了可直接复用的工业级代码实现。 阅读详情

相关推荐

字节跳动扣子AI应用开发平台之实战

推出背景:扣子平台由字节跳动推出,旨在让非开发者也能快速创建、调试和优化聊天机器人。上线时间:扣子平台于2024年2月1日正式上线。功能定位:扣子是一个AI聊天机器人和应用程序编辑开发平台,可以理解为字节跳动版的GPTs。

恩爸编程 5899

Python入门教程(从小白到高级)(新版)

Python从一无所知到精通(新版) 吐槽:Hello,everyone.经历完广东中考折磨的我回来啦!不得不说这届广东考生真的有些困难,先后经历了疫情,然后这次中考又来了一份折磨人的数学试卷(初高中衔接,难度我也觉得有些大)…最后我也不多说了,但愿看到这篇教程的广东初三中考生知道过去的都过去了,不要再这么纠结与郁闷。人生路漫漫,不必因为数学失利而感到绝望,毕竟你难别人也会觉得难,你死了别人也可能跟你一样陪葬。收拾好行装,整理好心态,重新出发,活在当下,为未来努力奋斗才是实在。同时也祝愿广州考生能在七月的中

weixin_47585269的博客 26万+

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(四)-无人机系统(UAS)命令与控制(C2)通信用例

UTM向5G网络提供无人机系统C2通信所需的信息,例如服务类别、无人机系统服务的流量类型、授权的无人机系统服务所需的QoS以及无人机系统服务的订阅。遵循模型B的网络辅助C2模型,为了确保UAS操作的C2通信的服务可用性和可靠性,特别是当无人机在操作员的视线之外(BLOS)飞行时,为无人机提供支持冗余的C2通信链路。如果需要创建额外的C2通信连接或更改现有数据连接的配置以进行C2通信,则5G网络会根据无人机系统的授权服务信息和C2通信中所需的QoS和优先级,修改或分配一个或多个C2通信流量的QoS流。

u011376987的博客 2053

10年程序员职业生涯感悟—写给正在迷茫的你

希望能带给大家不一样的参考。或者能提前预防,少走弯路!

pythonandaiot的博客 1万+

安装了anaconda,pycharm导入numpy时提示没有该包(模块)?

**问题详情:**我安装了anaconda,在利用Pycharm学习numpy这个库的时候,导入numpy这个包的时候提示我没有nummpy这个模块:No module named numpy.如下图所示。 应该说安装了Anaconda,里边就自带了numpy这个库,就应该能够使用。我一个新手怎么搞得懂呢?于是网上查了查找到了一个解决办法,说是我项目的解释器应该设置为Anaconda安装目录下的python.exe,而不应该是系统自带的:https://blog.youkuaiyun.com/aanndd77/art

qq_39820505的博客 1万+

cadence—virtuosoic617的使用技巧收集区

cadence使用

qq_33599939的博客 3万+

python入门教程(非常详细)

如果您是想学习Python编程的新手,以下是详细的Python入门教程,以帮助您快速掌握Python编程基础。如上代码中,`if-else`语句执行a的正负情况的判断,`while`语句实现了从0到5一共打印5次的循环输出,`for`语句遍历了列表words中的元素,依次输出。如上代码中,定义了一个求和函数`add`,并将两个参数相加后作为返回值返回,然后调用该函数,并将其结果赋值给变量`result`,最后输出结果。函数是Python中的基本组成部分之一,是将一段代码块独立的组合起来进行复用的有力工具。

weixin_55220738的博客 3万+

STM32 使用SYN6288语音模块

本篇文章带大家学习一下SYN6288语音模块,这个模块可以用于车载设备,语音电子书等众多产品当中,而且这个模块支持多种编码格式,GB2312,GBK等字符编码格式。SYN6288语音合成模块是一种语音合成设备,其可实现文字转语音功能,将输入的文字信息通过内部的处理和合成,输出相对应的语音信息。SYN6288模块具有语音合成质量高、输出音质好、使用方便等特点,因此广泛应用于语音播报、语音提示、语音识别、智能家居、智能家电、安防监控等领域。支持多语言:包括中文、英文、日文、韩文等多种语言。

m0_49476241的博客 2万+

python入门基础(完整)

python入门基础(完整) 安装及配置 使用的编程地址:编程地址 python基础相关文件安装: 链接:https://pan.baidu.com/s/1ZAhPIJ4_KAgWRHzX1lD3dQ 提取码:nxis pycharm配置环境 将原本pycharm中不可见的显示出,需要勾选以下三个:...

weixin_55154866的博客 2万+

基于STM32XX的LCD液晶显示屏(HS280S010B、驱动芯片:ST7789V)驱动C程序设计

/ 16位/pixel (RGB565)#define LCD_WIDTH 240 // 屏幕宽度。#define LCD_HEIGHT 280 // 屏幕高度。LCD_ROTATION_180, // 180度旋转。LCD_ROTATION_270 // 270度旋转。LCD_ROTATION_90, // 90度旋转。LCD_ROTATION_0 = 0, // 0度旋转。

myron6688的博客 370

ICC2(一)import design —— tluplus

itf转tluplus相关命令 TLUPlus是存储RC系数的二进制表格式。 TLUPlus模型通过包括宽度,空间,密度和温度对电阻系数的影响,可以估算RC计算net delay。 1.2 产生TLUplus的方法 Itf文件转TLUplus的命令: grdgenxo -itf2TLUPlus -i xx.itf-o xx.tlu+ itf: interconnect technology format file 含每层的厚度,面积等参数 itf同样可以转nxtgrd格式文...

m0_61544122的博客 5485

python入门教程(非常详细),从零基础入门到精通,看完这一篇就够了

前言本文罗列了了python零基础入门到精通的详细教程,内容均以知识目录的形式展开。01.python由来与发展介绍02.项目开发流程第一章 markdown编辑器01.markdown基本语法02.Typora简介与安装03.Windows上gitee+Typora设置图床04.macOS上gitee+Typora设置图床第二章 计算机核心基础01.计算机组成原理第三章 编程语言01.编程语言介绍02.python是解释型的强类型动态语言第四章 Python解释器和集成环境。

优快云_430422的博客 1万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

人人都能看懂的 Python 装饰器入门教程

大家好,我是萱萱! 之前的文章中提到,很多人认为理解了装饰器的概念和用法后,会觉得自己的 Python 水平有一个明显的提高。 但很多教程在一上来就会给出装饰器的定义以及基本用法,例如你一定会在很多文章中看到例如代码运行时间计时器等相关常用装饰器。 直接从应用入手这样学习当然十分有效,但不是看过就忘就是似懂非懂的状态,因为装饰器从来就不是一个单独的概念,就像数学分析中求积分一样,你可以通过公式快速算出需要求的积分,但是若明白积分是由极限定义的,之后再看积分将会是不一样的视角。 本文我将尝试说清楚为什么需要

梦子微信 334

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

理解Python中的装饰器

ddd

临渊-测试开发 1055

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

5分钟掌握 Python 中的装饰器

↑↑↑关注后"星标"简说Python 人人都可以简单入门Python、爬虫、数据分析 简说Python推荐 来源:Python中文社区作者:巩庆奎 python中的装饰...

简说Python的博客 337

[每日一题]26、一文搞懂Python装饰器

点击上方“Python3X”,选择“置顶或者星标”第一时间收到精彩推送!Python Every Day, 第 26 天装饰器是Python非常重要的一部分,作用是为了增...

胖虎 270

理解 Python 中的装饰器

前言 装饰器是Python中的一个重要概念,多用于在不修改原函数的基础上,为函数增加额外的功能。 基础装饰器 例如小李给女朋友买了一款iPhone12作为生日礼物,手机原封未拆封。 def gift(): print('iPhone12') gift() # 运行显示礼物信息 但还是觉得礼物太单薄,于是又买了一盒德芙巧克力,一支dior的口红,并找了个精美的礼品盒包装了一下,盒子里放满了泡沫球。 ...

we 362

【Python学习教程】:装饰器的详细教程,通俗易懂

装饰器是Python中的一个重要概念,多用于在不修改原函数的基础上,为函数增加额外的功能。 基础装饰器 例如小李给女朋友买了一款iPhone12作为生日礼物,手机原封未拆封。 def gift(): print('iPhone12') gift() # 运行显示礼物信息 但还是觉得礼物太单薄,于是又买了一盒德芙巧克力,一支dior的口红,并找了个精美的礼品盒包装了一下,盒子里放满了泡沫球。 ''' 学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025 寻找有

Python热爱者的博客 568

人人都能看懂的「迭代器、生成器」入门指南!

大家好。 这是「人人都能看懂的 Python 进阶」系列。 今天我们将讨论能在很多教程中看到,但又常常搞的头晕转向的迭代器、生成器,以及让新手经常困惑的yield。 事实上,和装饰器一样,这三个概念也是绑在一起的,例如你想知道 「什么是yield」,那在这之前你必须了解什么是生成器。不过在了解生成器之前,又必须了解什么是迭代器,但在搞明白迭代器之前,你总要知道什么是可迭代对象吧。 下面就让我们按照这个思路,来一点一点前进吧。 一、迭代器 1. 迭代 在介绍一切之前,先说一下最简单的迭代 &

早起Python 618

【Python进阶】拷贝、闭包、装饰器,函数分类

Python进阶之深浅拷贝,对象属性和类属性,类方法和静态方法,闭包,函数分类

weixin_52854743的博客 2128

Python_拷贝、闭包、装饰器-7

能够知道类属性,类方法,静态方法的使用掌握闭包的构成条件【重点】有嵌套有引用有返回能够知道装饰器的使用【重点】​ @装饰器名==目标:==掌握函数的快速使用。在之前的学习中,已经学习过函数。一起来看看简单和综合函数语法格式。# 定义def 函数名():代码...# 调用函数名()# 定义def 函数名([参数1, 参数2, 参数3, ...]):代码...[return 值]# 调用函数名([值1, 值2, 值3, ...])(1)先定义,后调用;

AGI爱好者_数仓&可视化&数据分析工程师_Vae’伯乐‘ 1084

Python进阶

ddd

临渊-测试开发 1065
上一篇: 男女洗澡前后区别,太形象了!
下一篇: 推荐9个鲜为人知的Python第三方库
菜鸟学Python
博客等级 码龄9年 8083粉丝 571原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值