sys、shutil、os与pathlib常用方法介绍与总结

sys模块

关于这个模块我用的还真不是很多,可能是因为在win下开发不多,大多数情况os都能基本胜任,而sys用的最多的可能就是sys.argv,通过代码获取命令行参数,之后在介绍具体的例子,如果说常见的函数,可能就如下的6个。

(1) sys.argv 实现从程序外部向程序传递参数
sys.argv 变量是一个包含了命令行参数的字符串列表, 利用命令行想程序传递参数. 其中,脚本的名称总是 sys.argv 列表的第一个参数。

(2) sys.path 包含输入模块的目录名列表。
获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到。在import导入module_name时,就是根据sys.path的路径来搜索module.name,也可以自定义添加模块路径。
sys.path.append(“自定义模块路径”)

(3) sys.exit([arg]) 程序中间的退出, arg=0为正常退出
一般情况下执行到主程序末尾,解释器自动退出,但是如果需要中途退出程序,可以调用sys.exit函数,带有一个可选的整数参数返回给调用它的程序,表示你可以在主程序中捕获对sys.exit的调用。(0是正常退出,其他为异常)当然也可以用字符串参数,表示错误不成功的报错信息。

(4) sys.modules
sys.modules是一个全局字典,该字典是python启动后就加载在内存中。每当程序员导入新的模块,sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。它拥有字典所拥有的一切方法.

(5) sys.getdefaultencoding() / sys.setdefaultencoding() / sys.getfilesystemencoding()
sys.getdefaultencoding()
获取系统当前编码,一般默认为ascii。
sys.setdefaultencoding()
设置系统默认编码,执行dir(sys)时不会看到这个方法,在解释器中执行不通过,可以先执行reload(sys),在执行 setdefaultencoding(‘utf8’),此时将系统默认编码设置为utf8。(见设置系统默认编码 )
sys.getfilesystemencoding()
获取文件系统使用编码方式,Windows下返回’mbcs’,mac下返回’utf-8’

(6) sys.stdin, sys.stdout, sys.stderr
stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们.

引用自python之sys模块

大多数情况,如果我用sys.argv,基本都是和parse连用,因为这个能监测命令行输入的参数,根据用户的使用来区分功能,比如之前看flask小程序中有用到:

class runJob( Command ):

    capture_all_args = True
    def run(self,*args,**kwargs):
        args = sys.argv[2:]		# python manage runjob -m Test  (  jobs/tasks/Test.py ),args中最终拿到命令行中的任务名称或选项字符串列表
        parser = argparse.ArgumentParser( add_help = True )

        parser.add_argument("-m","--name",dest = "name",metavar = "name", help="指定job名",required=True)
        parser.add_argument("-a","--act",dest = "act",metavar = "act", help="Job动作",required=False)
        parser.add_argument("-p","--param",dest = "param",nargs = "*", metavar = "param",help="业务参数",default = '',required=False)
        params = parser.parse_args( args )
        params_dict = params.__dict__
        ret_params = {}
        for item in params_dict.keys():
            ret_params[ item ] = params_dict[ item ]

        if "name" not in ret_params or not ret_params['name']:
            return self.tips()

        module_name = ret_params['name'].replace( "/","." )
        try:
            import_string = "from jobs.tasks.%s import JobTask as  job_target" % ( module_name )
            exec( import_string , globals() )
            target = job_target()
            target.run( ret_params )
        except Exception as e:
            traceback.print_exc()

关于parse模块,可以看这篇Python利用argparse模块图片转字符文件

os模块与shutil模块

os.sep 可以取代操作系统特定的路径分隔符。windows下为 '\\'
os.name 字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是 'posix'
os.getcwd() 函数得到当前工作目录,即当前Python脚本工作的目录路径
os.getenv() 获取一个环境变量,如果没有返回none
os.putenv(key, value) 设置一个环境变量值
os.listdir(path) 返回指定目录下的所有文件和目录名
os.remove(path) 函数用来删除一个文件
os.system(command) 函数用来运行shell命令
os.linesep 字符串给出当前平台使用的行终止符。例如,Windows使用 '\r\n',Linux使用 '\n' 而Mac使用 '\r'
os.path.split(path)  函数返回一个路径的目录名和文件名
os.path.isfile() 和os.path.isdir()函数分别检验给出的路径是一个文件还是目录
os.path.exists() 函数用来检验给出的路径是否真地存在
os.curdir  返回当前目录 ('.')
os.mkdir(path) 创建一个目录
os.makedirs(path) 递归的创建目录
os.chdir(dirname) 改变工作目录到dirname    
os.path.getsize(name) 获得文件大小,如果name是目录返回0L
os.path.abspath(name) 获得绝对路径
os.path.normpath(path) 规范path字符串形式
os.path.splitext()  分离文件名与扩展名
os.path.join(path,name) 连接目录与文件名或目录
os.path.basename(path) 返回文件名
os.path.dirname(path) 返回文件路径
os.walk(top,topdown=True,onerror=None)  遍历迭代目录
os.rename(src, dst)  重命名file或者directory src到dst 如果dst是一个存在的directory, 将抛出OSError. 在Unix, 如果dst在存且是一个file, 如果用户有权限的话,它将被安静的替换. 操作将会失败在某些Unix 中如果src和dst在不同的文件系统中. 如果成功, 这命名操作将会是一个原子操作 (这是POSIX 需要). 在 Windows上, 如果dst已经存在, 将抛出OSError,即使它是一个文件. 在unix,Windows中有效。
os.renames(old, new) 递归重命名文件夹或者文件。像rename()

# shutil 模块
shutil.copyfile( src, dst) 从源src复制到dst中去。当然前提是目标地址是具备可写权限。抛出的异常信息为IOException. 如果当前的dst已存在的话就会被覆盖掉
shutil.move( src, dst)  移动文件或重命名
shutil.copymode( src, dst) 只是会复制其权限其他的东西是不会被复制的
shutil.copystat( src, dst) 复制权限、最后访问时间、最后修改时间
shutil.copy( src, dst)  复制一个文件到一个文件或一个目录
shutil.copy2( src, dst)  在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,类似于cp –p的东西
shutil.copy2( src, dst)  如果两个位置的文件系统是一样的话相当于是rename操作,只是改名;如果是不在相同的文件系统的话就是做move操作
shutil.copytree( olddir, newdir, True/Flase)
把olddir拷贝一份newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接
shutil.rmtree( src ) 递归删除一个目录以及目录内的所有内容

这个我也不记得具体引用在哪里了,菜鸟、某脚本、csdn、博客园查询os和shutil都是会黏贴这个,这也确实做了详细说明,我主要说一些我的使用经验。

为什么将os和shutil放一起来讲,很大程度上是因为这两个模块都是python的内置模块,shutil更可以看作是os的二次开发,因为os的api太多而独立出来的类,从功能来讲,os已经涵盖了Linux上全部的基本需求,而shutil更偏向文件权限操作,提高了文件操作的效率。

上述os提供的api基本上两两组合就能达到很多期望的效果,比如说我们想在某个路径下进行文件迁移,但需要判断是否存在该文件夹:

if (os.path.exists("/{0}/".format(xxxx)) == False):
    os.makedirs("/{0}/".format(xxxx))
shutil.move(local_path,)

文件遍历与复制:

import os, shutil

print(os.listdir(r'G:\要删的东西\opencv\template-matching-ocr'))
for file in os.listdir(r'G:\要删的东西\opencv\template-matching-ocr'):
    print(file)
    if os.path.splitext(file)[1] == ".py":
        print(file)
        shutil.copy(file, "a.py")

文件递归遍历与移动:

import os,shutil

for file in os.listdir(r'G:\要删的东西\opencv\template-matching-ocr'):
    for root, dirs, files in os.walk(r'G:\要删的东西\opencv\template-matching-ocr'):
        for file in files:
            if file.split(".")[1] == "py":
                shutil.move(os.path.join(root,file),nginx_path)

另外一些文件路径的操作如下:

def path_func():
    '''
    操作路径的函数
    '''
    paths = [r'file.txt', r"/python/lib/hello.py", r"/python/local/text.txt", "C:/python/local", "C:/python/file.txt"]
    strs = os.path.abspath(paths[0])
    print(strs,"......绝对路径")

    strs = os.path.basename(paths[1])  # 文件名
    print(strs,"......文件名")
    strs = os.path.dirname(paths[1])  # 文件夹名
    print(strs,"......文件夹名")
    strs = os.path.join("C:\\", r"a.txt")  # 将路径组合返回
    dirname, filename = os.path.split(paths[1])  # 分割路径 (目录 文件名)
    print(dirname,filename,".......目录,文件名")
    strs, text = os.path.splitext(paths[1])  # 分离扩展名 (前部分, 扩展名)
    drivename, pathname = os.path.splitdrive(paths[3])  # 分离目录 (盘符, 目录)
    size = os.path.getsize(paths[0])  # 文件大小
    print(size,"......文件大小")
    strs = os.path.normcase(paths[1])  # 规范大小写 (修改斜杠)
    print(strs,"......规范大小写")
    strs = os.path.normpath(paths[1])  # 规范斜杠 (修改斜杠)
    strs = os.path.realpath(paths[1])  # 规范名字 (全名)
    # relpath(paths[0], start=os.curdir)
    strs = os.path.relpath(paths[1])  # 当前路径的文件相对路径 => 'lib\\hello.py'
    boolean = os.path.exists(paths[1])  # 路径是否存在
    boolean = os.path.isabs(paths[1])  # 是否是绝对路径 (不准)
    boolean = os.path.isfile(paths[1])  # 是否是文件
    boolean = os.path.isdir(paths[1])  # 是否是文件夹
    boolean = os.path.islink(paths[1])  # 是否是软链接
    boolean = os.path.ismount("C:\\")  # 是否是根结点
    boolean = os.path.supports_unicode_filenames  # Unicode是否可用作文件名
    boolean = os.path.samefile(paths[0], paths[0])  # 是否指向同文件或目录
    boolean = os.path.sameopenfile(os.open(paths[0], 1), os.open(paths[0], 1))  # fd是否指向同一文件
    boolean = os.path.samestat(os.stat(paths[0]), os.stat(paths[0]))  # state是否指向同一文件
    time_s = os.path.getatime(paths[0])  # 获取访问时间
    print(time_s,"......获取访问时间")
    time_s = os.path.getmtime(paths[0])  # 获取修改时间
    print(time_s, "......获取修改时间")
    time_s = os.path.getctime(paths[0])  # 元数据修改时间
    print(time_s, "......原数据修改时间")

"""
D:\code\untitled\file.txt ......绝对路径
hello.py ......文件名
/python/lib ......文件夹名
/python/lib hello.py .......目录,文件名
4966932 ......文件大小
\python\lib\hello.py ......规范大小写
1600314895.6528695 ......获取访问时间
1600314895.6528695 ......获取修改时间
1600314641.2361176 ......原数据修改时间
"""

上面和下面的某些代码引用自:Python3 操作系统与路径 模块(os / os.path / pathlib)

获取文件信息:

import os

for dir in os.scandir():
    strs = dir.name  # 文件名
    path = dir.path  # 完整路径名
    num = dir.inode()  # inode编号
    boolean1 = dir.is_dir()  # 是否是文件夹
    boolean2 = dir.is_file()  # 是否是文件
    boolean3 = dir.is_symlink()  # 是否是链接
    tups = dir.stat()  # 状态信息的stat_result对象
    print("文件名:",strs,"完整路径名:",path,"inode编号:",num,"是否是文件夹:",boolean1,
          "是否是文件:",boolean2,"是否是链接:",boolean3,"状态信息的stat_result对象:",tups)

"""
文件名: celerylog.log 完整路径名: .\celerylog.log inode编号: 1688849860420478 是否是文件夹: False 是否是文件: True 是否是链接: False 状态信息的stat_result对象: os.stat_result(st_mode=33206, st_ino=0, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=0, st_atime=1600248910, st_mtime=1600248910, st_ctime=1600248910)
文件名: config.py 完整路径名: .\config.py inode编号: 3659174697372719 是否是文件夹: False 是否是文件: True 是否是链接: False 状态信息的stat_result对象: os.stat_result(st_mode=33206, st_ino=0, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=250, st_atime=1600248646, st_mtime=1600248646, st_ctime=1600248449)
文件名: file.txt 完整路径名: .\file.txt inode编号: 844424930288790 是否是文件夹: False 是否是文件: True 是否是链接: False 状态信息的stat_result对象: os.stat_result(st_mode=33206, st_ino=0, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=4966932, st_atime=1600314895, st_mtime=1600314895, st_ctime=1600314641)

"""

获取系统信息:

def os_func():
    '''
    操作系统模块
     该模块下的方法,对各个版本的兼容不明确,须谨慎使用.
     测试版本: Python:3.6.1 Windows:Windows10,64bit
    '''
    # === 系统 ===
    strs = os.name  # 当前系统: Linux'posix' / Windows'nt' / 'ce' / 'java'
    strs = os.sep  # 分隔符 \\ (windows:\\ linux:/)
    strs = os.pathsep  # path变量分隔符 ; (windows:; linux::)
    strs = os.linesep  # 换行分隔符 \r\n (windows:/r/n linux:\n)
    dics = os.environ  # 查看系统环境变量(字典)
    strs = os.getenv("Path", default=-1)  # 读取环境变量, 没有返回None
    os.putenv("Path", "C:\\python")  # 添加环境变量 (windows无效)
    os.unsetenv("Path")  # 删除环境变量 (windows不可用)
    strs = os.getlogin()  # 当前登录的用户名
    num = os.getpid()  # 当前进程PID
    num = os.system("cmd")  # 执行操作系统命令, 返回0/1(0执行正确;1执行错误)
    strs = os.popen("dir").read()  # 执行系统命令,并去读结果
    tups = os.times()  # 当前进程时间(user用户 / system系统 / children_user子用户(windews=0) / children_system子系统(windews=0) / elapsed过去时间)
    bytes = os.urandom(10)  # n字节用以加密的随机字符
    num = os.cpu_count()  # CUP数量

    # === 进程 ===
    os.abort()  # 结束进程
    # execl(file, *args) / execle / execlp / execlpe / execv / execve / execvp / execvpe // 运行新程序替换当前进程
    os.execl(r"C:\python", 'python', 'hello.py', 'i')  # (windows执行失败)
    os._exit(0)  # 退出
    os.kill(8480,
            signal.SIGTERM)  # (系统) 终止进程(需要导入:signal) SIGINT (终止进程) / SIGTERM (终止进程) / SIGKILL (终止进程) / SIGALRM (闹钟信号)

pathlib

pathlib 提供表示文件系统路径的类,其语义适用于不同的操作系统。路径类在纯路径之间划分,纯路径提供纯粹的计算操作而没有I / O,以及具体路径,它继承纯路径但也提供I / O操作。如果你以前从未使用过这个模块,或者只是不确定哪个类适合您的任务,那么 Path 很可能就是您所需要的。他会为代码运行的不同的系统实例化属于该系统的具体路径,而不需要你自己设定

所以对于os的很多方法pathlib进行了升级,比如上面的os.walk()可以替换成path.rglob,更为简洁与方便,直接拿到所有对应的路径:

from pathlib import Path

path = Path(r"D:\code\dingshirenwu")
# 递归获取并筛选
for p in path.rglob("*.py"):
    print(str(p))

打印某目录下所有文件的第一行:

import pathlib

def pathlib_demo(path):
    path = pathlib.Path(path)
    path_iter = path.iterdir()  # 遍历目录
    for path in path_iter:
        file_bool = path.is_file
        if not file_bool:
            continue
        print(">>> {}".format(path))    # 打印打开文件的路径
        f = path.open()  # 是文件就打开读点内容
        data = f.readline()     # 读取第一行文件
        print(data)
        f.close()

pathlib_demo(r"D:\code\dingshirenwu\test")

"""
>>> D:\code\dingshirenwu\test\ingress.py
a = {"abc":"11111","videoflag":1,"aaaa":"123","dddd":333}

>>> D:\code\dingshirenwu\test\ingress1.py
a = {"abc":"11111","videoflag":1,"aaaa":"123","dddd":333}

>>> D:\code\dingshirenwu\test\ingress2.py
a = {"abc":"11111","videoflag":1,"aaaa":"123","dddd":333}

>>> D:\code\dingshirenwu\test\setuptools.pth
./setuptools-40.8.0-py3.7.egg
"""

当然也可以根据业务改成特定格式的所有数据第一行,这个业务可能出现场景是文件需要批量上传到客户端,但文件名没有做区分,所以我们需要读取某一行拿到特定值进行按类别投递。

对照关联表

functionos or os.pathpathlib
检验权限模式os.access()
改变当前工作目录os.chdir()
设置路径的标记为数字标记os.chflags()
更改权限os.chmod()Path.chmod()
更改文件所有者os.chown()
改变当前进程的根目录os.chroot()
关闭文件描述符 fdos.close()
关闭所有文件描述符os.closerange()
复制文件描述符 fdos.dup(fd)
将一个文件描述符 fd 复制到另一个 fd2os.dup2(fd, fd2)
通过文件描述符改变当前工作目录os.fchdir(fd)
改变一个文件的访问权限os.fchmod(fd, mode)
修改一个文件的所有权os.fchown(fd, uid, gid)
强制将文件写入磁盘os.fdatasync(fd)
通过文件描述符创建一个文件对象os.fdopen()
返回一个打开的文件的系统配置信息os.fpathconf(fd, name)
返回文件描述符fd的状态os.fstat(fd)
返回包含文件描述符fd的文件的文件系统的信息os.fstatvfs(fd)
强制将文件描述符为fd的文件写入硬盘os.fsync(fd)
裁剪文件描述符fd对应的文件os.ftruncate(fd, length)
返回当前工作目录os.getcwd()Path.cwd()
返回一个当前工作目录的Unicode对象os.getcwdu()
判断与tty(-like)设备相连是否正确os.isatty(fd)
设置路径的标记为数字标记,但是没有软链接os.lchflags(path, flags)
修改连接文件权限os.lchmod(path, mode)
更改文件所有者,类似 chown,但是不追踪链接os.lchown(path, uid, gid)
创建硬链接,名为参数 dst,指向参数 srcos.link(src, dst)
返回path指定的文件夹包含的文件或文件夹的名字的列表os.listdir(path)Path.iterdir()
设置文件描述符 fd当前位置为pos, how方式修改os.lseek(fd, pos, how)
像stat(),但是没有软链接os.lstat(path)
从原始的设备号中提取设备major号码os.major(device)
递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹os.makedev(major, minor)
递归文件夹创建函数os.makedirs(path[, mode])
从原始的设备号中提取设备minor号码os.minor(device)
创建文件夹os.mkdir()Path.mkdir()
创建命名管道,mode 为数字,默认为 0666 (八进制)os.mkfifo(path[, mode])
创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)os.mknod(filename[, mode=0600, device])
打开一个文件,并且设置需要的打开选项,mode参数是可选的os.open(file, flags[, mode])
打开一个新的伪终端对。返回 pty 和 tty的文件描述符os.openpty()
返回相关文件的系统配置信息os.pathconf(path, name)
创建一个管道. 返回一对文件描述符(r, w) 分别为读和写os.pipe()
从一个 command 打开一个管道os.popen(command[, mode[, bufsize]])
从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串os.read(fd, n)
返回软链接所指向的文件os.readlink(path)
删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directoryos.remove()Path.unlink()
递归删除目录os.removedirs(path)
Path.replace()
重命名文件或目录os.rename()Path.rename()
递归地对目录进行更名,也可以对文件进行更名os.renames(old, new)
删除path指定的空目录,如果目录非空,则抛出一个OSError异常os.rmdir()Path.rmdir()
获取path指定的路径的信息,功能等同于C API中的stat()系统调用os.stat()Path.stat(), Path.owner(), Path.group()
决定stat_result是否以float对象显示时间戳os.stat_float_times([newvalue])
获取指定路径的文件系统统计信息os.statvfs(path)
创建一个软链接os.symlink(src, dst)
返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组os.tcgetpgrp(fd)
设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pgos.tcsetpgrp(fd, pg)
返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常os.ttyname(fd)
删除文件路径os.unlink(path)Path.unlink()
返回指定的path文件的访问和修改的时间os.utime(path, times)
输出在文件夹中的文件名通过在树中游走,向上或者向下os.walk()Path.glob()、Path.rglob()
写入字符串到文件描述符 fd中. 返回实际写入的字符串长度os.write(fd, str)
------------------------------------------------------------------------------------------------
返回绝对路径os.path.abspath()Path.resolve()
“a/b/c.d” => “c.d”os.path.basename()Path.name()
返回list(多个路径)中,所有path共有的最长的路径os.path.commonprefix(list)
“a/b/c.d” => “a/b”os.path.dirname()PurePath.parent
路径存在则返回True,路径损坏返回Falseos.path.exists()Path.exists()
路径存在则返回True,路径损坏也返回Trueos.path.lexists
把path中包含的"~“和”~user"转换成用户目录os.path.expanduser()Path.expanduser() and Path.home()
根据环境变量的值替换path中包含的"$name"和"${name}"os.path.expandvars(path)
返回最近访问时间(浮点型秒数)os.path.getatime(path)
返回最近文件修改时间os.path.getmtime(path)
返回文件 path 创建时间os.path.getctime(path)
os.path.getsize(path)os.path.getsize(path)
判断是否为绝对路径os.path.isabs()PurePath.is_absolute()
判断路径是否为文件os.path.isfile()Path.is_file()
判断路径是否为目录os.path.isdir()Path.is_dir()
判断路径是否为链接os.path.islink()Path.is_symlink()
判断路径是否为挂载点os.path.ismount(path)
拼接路径os.path.join()Path.joinpath()
转换path的大小写和斜杠os.path.normcase(path)
规范path字符串形式os.path.normpath(path)
返回path的真实路径os.path.realpath(path)
从start开始计算相对路径os.path.relpath(path[, start])
判断目录或文件是否相同os.path.samefile()Path.samefile()
判断fp1和fp2是否指向同一文件os.path.sameopenfile(fp1, fp2)
判断stat tuple stat1和stat2是否指向同一个文件os.path.samestat(stat1, stat2)
“a/b/c.d” => (“a/b”, “c.d”)os.path.split(path)
一般用在 windows 下,返回驱动器名和路径组成的元组os.path.splitdrive(path)
“a/b/c.d” => (‘a/b/c’, ‘.d’)os.path.splitext()PurePath.suffix
把路径分割为加载点与文件os.path.splitunc(path)
遍历pathos.path.walk()
设置是否支持unicode路径名os.path.supports_unicode_filenames()

在这里插入图片描述


参考与推荐:

[1].pathlib模块

[2].【Python 笔记】Python操作文件系统路径——os.path 和 pathlib

[3].python之shutil模块详解

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

submarineas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值