Skip to main content

扩展库介绍

这是中国传媒大学胡凤国老师上课分享的自定义函数库,最初包含几个常用的文本处理及目录操作函数,后来又陆续添加了其它功能。发布本扩展库主要是方便上课学生练习Python程序,顺便分享给其他需要的Pythoner。

刚学会发布扩展库,PyPI很多东西还不熟,代码力求多平台通用,已经在Windows下进行了测试,Linux和mac下可能存在一些问题,如有问题,请多提宝贵意见。

最近更新日期:2026年8月22日,主要是修正了my_path2path函数的一个小BUG。

安装说明

环境要求

  • 所需Python版本:Python 3.6+
  • 推荐Python版本:Python 3.8+

初次安装

如果电脑上安装了多个版本的Python,pip命令安装扩展库时需要指定Python软件的版本号,例如:pip3.6、pip3.8、pip3.9、pip3.14、……、等等。如果只安装了一个版本的Python软件,那么,可以直接写pip不用带Python的版本号。下面的安装命令假设电脑上只安装了一个版本的Python软件。

仅安装核心模块

pip install hufengguo

安装所有模块

pip install "hufengguo[all]"

安装 GUI 处理功能

pip install "hufengguo[gui]"

安装 PDF 处理功能

pip install "hufengguo[pdf]"

更新安装

pip install -U 所需模块

用法说明

基本用法见胡凤国老师的上课教材:《Python程序设计(基于计算思维和新文科建设)》,ISBN:9787121435577,胡凤国,电子工业出版社,2022年6月。

这里举一些简单的例子。

产生1到100之内的素数

# 导入
from hufengguo import isprime

# 产生素数列表
x = [i for i in range(101) if isprime(i)]

# 输出
print(x)

去掉多行文本中的空白行和每行首尾空白符

# 导入
from hufengguo import remove_white_from_text

# 赋值
s = "\t\n\n  今天是个好日子,\t\n  \n  \t心想的事儿都能成。\n \n\n"

# 去掉多行文本中的空白行和每行首尾空白
print("="*10)
print(remove_white_from_text(s))
print("="*10)

# 去掉去掉多行文本中的每行首尾空白、前面空白,第一行非空内容之后多个空白行保留一个
print(remove_white_from_text(s, keep_one_empty_line=True))
print("="*10)

随机生成若干个长度介于指定范围内的密码字符串

# 导入
from hufengguo import gen_pwd

# 产生一个长度为6的密码,密码字符包含大小写英文字母和数字
print(gen_pwd(6))

# 产生一个长度为在4到8之间的密码(含4和8),密码字符包含大小写英文字母和数字
print(gen_pwd(4, 8))

# 产生一个长度为在4到8之间的密码(含4和8),密码字符包含大小写英文字母、数字和标点符号
print(gen_pwd(4, 8, punct=True))

# 产生一个长度为在4到8之间的密码(含4和8),密码字符包含大小写英文字母
print(gen_pwd(4, 8, digit=False))

# 产生一个长度为在4到8之间的密码(含4和8),密码字符包含大写英文字母和数字
print(gen_pwd(4, 8, lower=False))

# 产生一个长度为在4到8之间的密码(含4和8),密码字符包含小写英文字母和数字
print(gen_pwd(4, 8, upper=False))

# 产生5个长度为在4到8之间的密码(含4和8)
print(gen_pwd(4, 8, count=5))

# 产生5个长度为在4到8之间的密码(含4和8),所有密码等长
print(gen_pwd(4, 8, count=5, samelen=True))

数字与汉字读法互转

本库采用我国传统数学的大数体系:零一二三四五六七八九十百千万亿兆京垓秭穰沟涧正载极。从十开始逢十进位;从万开始逢万进位,1兆等于1万亿(10的12次方),1京等于1万兆(10的16次方),……,1极等于1万载(10的48次方),传统大数体系可以表示长达96位数字。本库既支持长达96位数字的传统大数体系,又支持目前只通过万和亿循环的大数表示方法。

# 导入
from hufengguo import digit2hanzi, hanzi2digit

# 汉字转数字
print(hanzi2digit("一百二十三"))
print(hanzi2digit("壹佰贰拾叁"))
print(hanzi2digit("三兆"))
print(hanzi2digit("三万亿"))
print(hanzi2digit("一京"))
print(hanzi2digit("一亿亿"))
print(hanzi2digit("万"))       # 输出-1,因为它不是正常的数字读法
print(hanzi2digit("千"))       # 输出-1,因为它不是正常的数字读法
print(hanzi2digit("亿"))       # 输出-1,因为它不是正常的数字读法

# 非负整数转汉字
# daxieflag=True表示汉字读法用人民币金额大写的形式给出结果
# wanyiflag=True表示沿用目前的读法,万亿不写为兆,亿亿不写为京,……
print(digit2hanzi(123))
print(digit2hanzi(123, daxieflag=True))
print(digit2hanzi(3*10**12))
print(digit2hanzi(3*10**12, wanyiflag=True))
print(digit2hanzi(1234500000000))
print(digit2hanzi(1234500000000, wanyiflag=True))
print(digit2hanzi(12345000000000000))
print(digit2hanzi(12345000000000000, wanyiflag=True))
print(digit2hanzi(0))
print(digit2hanzi(-1))     # 参数非法,输出空字符串

人民币金额的正常汉字写法与大写写法互转

# 导入
from hufengguo import xiao2da, da2xiao

# 转换
print(xiao2da("一万二千三百零六"))
print(da2xiao("壹万贰仟叁佰零陆"))

分节格式化数字

# 导入
from hufengguo import fenjie_number

# 分节格式化操作
print(fenjie_number(12345678901, group=3))           # 3位一组,半角逗号隔开
print(fenjie_number(12345678901, group=3, sep="_"))  # 3位一组,半角下划线隔开
print(fenjie_number(12345678901))                    # 4位一组,半角空格隔开
print(fenjie_number(12345678901, group=4))           # 4位一组,半角空格隔开
print(fenjie_number(12345678901, group=5, sep=","))  # 5位一组,半角逗号隔开
print(fenjie_number(-1234567))                       # 4位一组,半角空格隔开

注意:分节格式化数字的函数 fenjie_number 最初发布时包含两个m,形式是 fenjie_nummber ,现予以纠正,变成一个m的函数,同时为了保证兼容性,两个m的函数将继续保留。

# 导入
from hufengguo import fenjie_nummber

# 分节格式化操作
print(fenjie_nummber(12345678901, group=3))           # 3位一组,半角逗号隔开
print(fenjie_nummber(12345678901, group=3, sep="_"))  # 3位一组,半角下划线隔开
print(fenjie_nummber(12345678901))                    # 4位一组,半角空格隔开
print(fenjie_nummber(12345678901, group=4))           # 4位一组,半角空格隔开
print(fenjie_nummber(12345678901, group=5, sep=","))  # 5位一组,半角逗号隔开
print(fenjie_nummber(-1234567))                       # 4位一组,半角空格隔开

读写文本文件

本库提供了两个函数来帮我们方便地读写文本文件。

函数 my_read_from_txtfile 会自动判断文本文件编码并读取其内容为字符串,它调用了chardet的自动判断文件编码功能;

函数 my_write_to_txtfile 会根据指定的文件名、字符串和指定的编码生成文本文件,编码支持Windows 10的记事本所自带的五种编码,默认编码是带有BOM的UTF-8编码;当文件所在目录不存在时,能自动创建文件所在目录。

这两个文件均支持文件名末尾带有空格的情况,我们用Python内置的open函数来读写文本文件是不支持这种情况的。

# 导入
from hufengguo import my_read_from_txtfile, my_write_to_txtfile

# 赋值
fn = r"abc \xyz "   # 注意目录名和文件名最后均有空格

# 生成文件,它会自动创建文件所在的目录
# 默认生成的文本文件编码是带有BOM的UTF-8编码,我们生成文件时可以用encoding参数指定文本文件的编码
my_write_to_txtfile(fn, "今天天气哈哈哈", encoding="gb18030")

# 读取文件,它会自动判定文本文件的编码
print(f"文件“{fn}”内容是:{my_read_from_txtfile(fn)}")

注意,在Windows下,这个生成的文件用os.path.exists是检测不到它的存在的,这个生成的文件用os.remove是删不掉的,手动删除也删不掉。与此类似,这个生成的文件所在目录用shutil.rmtree是删不掉的,手动删除也删不掉。

用本库提供的其它函数可以判定这一类文件的存在性,也可以删除这一类的文件和目录,后面会举例。

判断文件和目录的存在性的通用函数

前面提到,有一些文件名和目录名最后带有空格,它们的存在性用os.path.exists是检测不到,它们用os.remove和shutil.rmtree删不掉,本库提供了三个函数来做这个事情,这三个函数是通用的,同时适用于普通文件和目录,也适用于名称最后带有空格的文件和目录。

# 导入
from os.path import dirname, exists
from os import remove
from shutil import rmtree
from hufengguo import my_write_to_txtfile, make_dir_exists, my_exists, my_os_remove, my_shutil_rmtree

# 赋值
fn = r"abc \xyz "   # 注意目录名和文件名最后均有空格
d = dirname(fn)

# 生成目录和文件
print(make_dir_exists(d))
my_write_to_txtfile(fn, "今天天气哈哈哈")

# 判断文件和目录的存在性
print(f"用os.path.exists判定文件“{fn}”是否存在:{exists(fn)}")
print(f"用os.path.exists判定文件所在目录“{d}”是否存在:{exists(d)}")
print(fn, my_exists(fn))
print(d, my_exists(d))

# 删除文件和目录
try:
    remove(fn)
except Exception as e:
    print(f"用os.remove删除文件“{fn}”失败,错误信息是:{e}")
print(my_os_remove(fn))

try:
    rmtree(d)
except Exception as e:
    print(f"用shutil.rmtree删除文件所在目录“{d}”失败,错误信息是:{e}")
print(my_shutil_rmtree(d))

将来大家遇到文件名或目录名最后有空格手动删除不了的情况时,可以考虑使用本库提供的函数来帮你删掉。如果有特殊需要生成带空格的目录名和文件名,也可以使用本库提供的相应函数来达到目的。

获取当前Python程序文件所在的路径及相关路径

程序运行过程中,当前路径可能会变化,但Python程序文件所在的路径不会变化,这里给出的函数 my_abspath 能获取当前Python程序文件所在路径的绝对路径形式,以该路径为基础的一些路径也能获取。该函数的功能还不止这些,具体请参考下面的代码注释。

# 导入
from hufengguo import my_abspath

# 输出当前Python程序所在目录的绝对路径,注意,结果不一定是当前目录
# 如果是在Jupyter Notebook的单元格中运行,则获取当前Jupyter Notebook文档所在的绝对路径
# 如果是在Python文件打包成的exe文件中运行,则获取当前exe文件所在的绝对路径
# 为简单起见,后面的测试代码只说当前Python程序所在目录
p = my_abspath()
print([p])

# 输出当前Python程序所在目录下的“test.txt”的绝对路径
print(my_abspath(r"test.txt"))

# 输出当前Python程序所在目录下的上级目录下的“test.txt”的绝对路径
print(my_abspath(r"..\test.txt"))

# 输出当前Python程序所在目录下的“test ”的绝对路径
# 这里故意在最后加了一个空格
# Python的os.path.abspath会自动删掉最后的空格
print([my_abspath(r"test ")])

获取Windows桌面的全路径名

程序运行过程中,我们有时候会希望读取桌面的文件或者把文件生成到桌面上,本库提供了 my_desktop_path 函数来获取Windows桌面及相关的全路径名。

# 导入
from hufengguo import my_desktop_path

# 获取桌面的全路径名
p = my_desktop_path()
print(p)

# 获取桌面或其子孙目录中的文件的全路径名
p = my_desktop_path(r"abc\test.txt")
print(p)

测试文件只读属性三件套

下面这三个函数能判断文件的只读属性、为文件添加只读属性和去除文件的只读属性。

# 代入
from hufengguo import my_read_from_txtfile, my_write_to_txtfile, file_is_readonly, file_add_readonly, file_remove_readonly, my_os_remove

# 赋值
fn = "test12345.txt"

# 生成文件
my_write_to_txtfile(fn, "今天天气哈哈哈")
print(my_read_from_txtfile(fn))

# 第1次判断文件是否具有只读属性
print(file_is_readonly(fn))   # False

# 为文件添加只读属性
print(file_add_readonly(fn))

# 第2次判断文件是否具有只读属性
print(file_is_readonly(fn))   # True

# 取消只读
print(file_remove_readonly(fn))

# 第3次判断文件是否具有只读属性
print(file_is_readonly(fn))   # False

# 删除测试时生成的文件
print(my_os_remove(fn))

在目录及子目录下查找文件

# 导入
from hufengguo import find_files_walk, my_abspath

# 赋值,相对路径(相对于脚本目录)和绝对路径都行
# 如果p是相对路径,查找到的文件都是相对路径
# 如果p是绝对路径,查找到的文件都是绝对路径
p = r"abc"
# p = my_abspath(r"abc")

# 查找所有文件
files = find_files_walk(p)
print(*files, sep="\n")

print()

# 查找Word文件
files = find_files_walk(p, [".doc", ".docx"])
print(*files, sep="\n")

print()

# 查找文本文件
files = find_files_walk(p, [".txt"])
print(*files, sep="\n")

print()

# 查找没有扩展名的文件
files = find_files_walk(p, [""])
print(*files, sep="\n")

复制一个目录及子目录下指定类型的文件到另一个目录

本库提供的函数支持扁平化复制和保持目录结构复制。

# 导入
from hufengguo import copytree_filtered

# 复制
pathin, pathout1, pathout2 = r"in", r"out1", r"out1"
filetypes = [".doc", ".docx"]
copytree_filtered(pathin, pathout1, filetypes)                 # 扁平化复制目录树中指定类型的文件
copytree_filtered(pathin, pathout2, filetypes, flatten=False)  # 保持目录结构复制目录树中指定类型的文件

目录对目录操作示例

下面的代码把多对多的目录操作变成了单对单的文件操作,我们只需要写一个单对单的文件处理函数就好了。

# 导入
from hufengguo import my_read_from_txtfile, my_write_to_txtfile, remove_white_from_text, my_path2path

# 自定义函数:单对单文件操作示例,去掉文本文件中的空白行和每行首尾空白
def myfunc(fnin, fnout):
    s = my_read_from_txtfile(fnin)  # 读取
    t = remove_white_from_text(s)   # 操作
    my_write_to_txtfile(fnout, t)   # 写入

# 赋值
pathin = r"in"
filetypelist = [".txt"]
pathout = "out"
func = myfunc
outext = None

# 操作
my_path2path(pathin, filetypelist, pathout, func, outext)

分词操作

jieba库使用简单,本库中的几个分词和词性标注函数调用jieba库。

对多行文本进行分词,返回字符串

# 导入
from hufengguo import seg_str2str_by_jieba, segtag_str2str_by_jieba

# 准备文本
s = "\t\n\n  今天是个好日子,\t\n  \n心想的事儿\r都能成。\n \n\n"

# 分词
print("="*10)                                                           
print(seg_str2str_by_jieba(s))                                       
print("="*10)                                                           
print(seg_str2str_by_jieba(s, keep_empty_line=False))                
print("="*10)

print("\n"*2)

# 分词和词性标注
print("="*10)                                                           
print(segtag_str2str_by_jieba(s))                                       
print("="*10)                                                           
print(segtag_str2str_by_jieba(s, sepchar='|'))                          
print("="*10)                                                           
print(segtag_str2str_by_jieba(s, keep_empty_line=False))                
print("="*10)                                                           
print(segtag_str2str_by_jieba(s, sepchar='|', keep_empty_line=False))   
print("="*10)

调用jieba扩展库对一个文本文件进行分词和词性标注

# 导入
from hufengguo import segtag_by_jieba

# 对单文件进行分词和词性标注操作
segtag_by_jieba(r"in.txt", r"out.txt")

本函数会自动判断文本文件的编码并进行读取,生成文件的默认编码是utf-8-sig。

调用jieba扩展库对一个目录下的文本文件进行分词和词性标注

# 导入
from hufengguo import my_path2path, segtag_by_jieba

# 批量进行分词和词性标注操作
my_path2path(r"in", [".txt"], r"out", segtag_by_jieba)

本函数会自动搜索目录及子目录下的所有文本文件,进行分词和词性标注操作之后保存到目标目录,目标目录会保持跟源目录相同的目录结构。

本库提供的函数my_path2path()功能很强,它把目录对目录的多文件操作转化为单文件对单文件的操作。第二个参数可以换成其它的扩展名,第四个参数是一个函数名,我们可以换成其它的自定义函数来完成其它文本处理任务(要求自定义函数具有两个参数,第1个参数是源文件名,第2个参数是目标文件名,自定义函数的功能是对源文件进行自定义操作,操作结果写入目标文件)。

调用路径选择窗口类

独立调用

# 导入
from hufengguo import my_path2path, segtag_by_jieba
from hufengguo import MyFilePathWindow

# 自定义函数
def segtag(fnin, fnout):
    print(f"正在处理 {fnin} ……")
    segtag_by_jieba(fnin, fnout)

# 赋值
pin, pout = MyFilePathWindow(
        "分词和词性标注路径选择",
        file1flag=False,
        file2flag=False,
    ).show()

# 调用
if pin is None or pout is None:
    print("用户取消了操作。")
else:
    my_path2path(pin, [".txt"], pout, segtag)

集成调用

# 导入
from hufengguo import my_path2path, segtag_by_jieba, MyFilePathWindow
from tkinter import Button, Tk
from tkinter.messagebox import showinfo

# 自定义函数:对单个文本文件进行分词和词性标注
def segtag(fnin, fnout):
    # print(f"正在处理 {fnin} ……")
    segtag_by_jieba(fnin, fnout)

# 自定义函数,按钮响应函数
def do_segtag():
    fpin, fpout = MyFilePathWindow(
        "分词和词性标注路径选择",
        file1flag=False,
        file2flag=False,
        parent=main_app  # 指定父窗口
    ).show()
    
    if fpin and fpout:
        my_path2path(fpin, [".txt"], fpout, segtag)
        showinfo(title="信息反馈", message="操作完毕")
    else:
        showinfo(title="信息反馈", message="您取消了操作。")

# 界面
main_app = Tk()
main_app.title("主应用程序")
main_app.geometry("300x160")

Button(main_app, text="分词和词性标注", command=do_segtag).pack(pady=20)
Button(main_app, text="退出程序", command=main_app.destroy).pack()
main_app.mainloop()

PDF操作

保护PDF

from hufengguo import protect_pdf

fnin = r"test.pdf"
protect_pdf(fnin, r"test_默认保护.pdf")
protect_pdf(fnin, r"test_默认保护_用户密码12345.pdf", user_pwd="12345")
protect_pdf(fnin, r"test_默认保护_用户密码12345_所有者密码abcde.pdf",
            user_pwd="12345", owner_pwd="abcde")
protect_pdf(fnin, r"test_完全保护.pdf", -4096)

读取PDF的权限值

from hufengguo import get_pdf_permissions

fn = r"test.pdf"
r = get_pdf_permissions(fn)    # 如有密码,加第二个参数
print(*r.items(), sep="\n")

解密PDF文件并取消保护

from hufengguo import protect_pdf, get_pdf_permissions, decrypt_pdf

fnin, fntmp, fnout = r"test.pdf", r"tmp.pdf", r"test_out.pdf"
protect_pdf(fnin, fntmp, -4096, "12345")
decrypt_pdf(fntmp, fnout, "12345")
r = get_pdf_permissions(fnin)
print(*r.items(), sep="\n", end="\n\n")
r = get_pdf_permissions(fntmp, "12345")   # 如无密码,第二个参数省略
print(*r.items(), sep="\n", end="\n\n")
r = get_pdf_permissions(fnout, "12345")
print(*r.items(), sep="\n", end="\n\n")

分割PDF文件

from hufengguo import split_pdf

fnin, fnout = r"test.pdf", r"test_out.pdf"
split_pdf(fnin, fnout, 10, 15, pwd="你的密码")  # 如PDF文件有打开有密码,必须加pwd参数
split_pdf(fnin, None, 10, 15)      # 如省略输出文件名,则会构造输出文件名:test_10_15.pdf
split_pdf(fnin, None, 10, None)    # 如省略结束页编号,则认为是从第10页到结束
split_pdf(fnin, None, None, 10)    # 如省略开始页编号,则认为是从第1页到第10页

Metadata

Release files for hufengguo 1.3.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hufengguo 1.3.7
File Size Uploaded Provenance
hufengguo-1.3.7.tar.gz 40.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for hufengguo 1.3.7
File Interpreter ABI Platform
hufengguo-1.3.7-py3-none-any.whl Python 3 none any Details

Total release size: 76.8 kB

Release files / hufengguo-1.3.7.tar.gz

Download URL hufengguo-1.3.7.tar.gz
Size 40.9 kB
Tags Source
SHA-256 checksum
How to use checksums
b7a2d370be380a2df1a25ec781716fb1c2c7ff6dcfc983797f9101a53bc1f551
BLAKE2b-256 checksum
How to use checksums
8285296c75f0058fbdebb4b4f8a1081b6d6a3e64c2113d9bb192a907a89849fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.8.8

Release files / hufengguo-1.3.7-py3-none-any.whl

Download URL hufengguo-1.3.7-py3-none-any.whl
Size 35.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5b3e0f5a9a28b2c6b2e070eacd7ebf55d1deb91f32b0f63a27aa6874967220c1
BLAKE2b-256 checksum
How to use checksums
0059469aa5fbbc97c5b605f87cde0d787fe49d160524c91eae82a9895801b387
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.8.8

Security for hufengguo 1.3.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.3.7 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page