当前位置:首页>python>我用Python写CLI工具时,被argparse这个默认行为整了2小时

我用Python写CLI工具时,被argparse这个默认行为整了2小时

  • 2026-07-03 02:16:28
我用Python写CLI工具时,被argparse这个默认行为整了2小时

一个命令行参数解析的坑,让我彻底搞懂了argparse和click的区别


昨天帮朋友写了个批量重命名文件的小工具,本身功能很简单,就是把一个文件夹里的文件按顺序加上编号前缀
需求听起来很普通,对吧

# rename_files.py
import os
import argparse

defrename_files(directory, prefix):
    files = sorted(os.listdir(directory))
for i, filename inenumerate(files, 1):
        old_path = os.path.join(directory, filename)
        new_name = f"{prefix}_{i:03d}_{filename}"
        new_path = os.path.join(directory, new_name)
        os.rename(old_path, new_path)
print(f"Renamed: {filename} -> {new_name}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="批量重命名文件")
    parser.add_argument("directory"help="目标目录")
    parser.add_argument("--prefix""-p", default="file"help="文件名前缀")

    args = parser.parse_args()
    rename_files(args.directory, args.prefix)

写完一测试,效果还行
但朋友提了个需求:能不能加个预览模式
就是先显示一下将要重命名成什么样,但不改动实际文件名

这需求很合理,我就加了:

    parser.add_argument("--preview""-v", action="store_true"help="预览模式")

然后在主函数里加个判断:

if args.preview:
print(f"[PREVIEW] Would rename: {filename} -> {new_name}")
else:
        os.rename(old_path, new_path)
print(f"Renamed: {filename} -> {new_name}")

当时我觉得,这代码写得没问题啊,action="store_true" 是 argparse 的基础知识了好吗


第一次测试,问题来了

我在命令行测试:

$ python rename_files.py ./test_folder --preview

**居然真的执行了重命名操作
** 预览模式完全没有生效

我当时的反应:

让我手动执行一遍看看输出:

$ python rename_files.py ./test_folder -v

输出:

Renamed: a.txt -> file_001_a.txt
Renamed: b.txt -> file_002_b.txt
Renamed: c.txt -> file_003_c.txt

它直接给我重命名了
说好的预览模式呢


排查过程

我开始怀疑人生
第一个想法:难道 action 的语法写错了

我去查了一下 argparse 文档,确认没问题
store_true 的意思就是:如果命令行指定了这个选项,变量值为 True;否则默认为 False

让我加个打印看看 args.preview 的值:

print(f"Preview mode: {args.preview}")

再跑一次:

$ python rename_files.py ./test_folder -v
Preview mode: False
Renamed: a.txt -> file_001_a.txt

**args.preview 是 False
**

这就很离谱了
我明确传了 -v 参数,结果它告诉我 preview 是 False

我开始怀疑是不是因为 -v 和 -p(prefix)冲突了
虽然一个是短选项一个长选项,但 argparse 不会搞错吧

让我试试 --preview

$ python rename_files.py ./test_folder --preview
Preview mode: False
Renamed: a.txt -> file_001_a.txt

还是 False

我甚至怀疑是不是 Python 版本问题
我检查了一下:

$ python --version
Python 3.11.4

3.11,总不能是 argparse 的 bug 吧


柳暗花明

排查了大概一小时后,我决定重新仔细看一下代码

突然,我注意到了一个问题:

parser.add_argument("directory"help="目标目录")
parser.add_argument("--preview""-v", action="store_true"help="预览模式")

我之前定义的 directory 是位置参数,没有 - 前缀
那我刚才执行命令的时候,传入的参数顺序是:

$ python rename_files.py ./test_folder -v


我想起来了点什么

让我看看 argparse 是怎么解析的
我加了个调试:

print(f"args: {args}")
print(f"args.directory: {args.directory}")

再跑:

$ python rename_files.py ./test_folder -v
args: Namespace(directory='-v', prefix='file', preview=False)
args.directory: -v

**我擦
**

./test_folder 被当成了 prefix 参数的值,而 -v 被当成了 directory

这是因为 argparse 的解析顺序问题
当我写:

python rename_files.py ./test_folder -v

argparse 是这样解析的:

  • • ./test_folder → 因为 prefix 有默认值,它被跳过了
  • • -v → 剩下的第一个非选项参数,被当成 directory

所以实际上 directory 的值变成了 -v,而不是 ./test_folder

我之前的测试目录里其实是空的(或者目录不存在),所以没报错,只是悄悄做了错误的事情


第二次尝试修复

找到问题后,我觉得很简单:把 -v 改成 --preview 不就行了

但问题是,如果用户习惯性地用 -v 呢
虽然这个工具不是什么大项目,但用户体验还是要的嘛

另一个思路:把 --prefix 的位置改一下,不要让它紧跟在 directory 后面

但 argparse 的参数顺序本身就是按添加顺序来的,这没法控制

我尝试了一种方案:用 -- 来分隔位置参数和可选参数:

$ python rename_files.py ./test_folder -- -v

但这不对, -v 本身不是 directory 的值,它是 preview 的 flag

我陷入了死胡同


最后的解决方案

经过各种尝试,我决定换个思路:既然 argparse 的 positional argument 这么难搞,那我就把所有参数都改成可选参数好了

import os
import argparse

defrename_files(directory, prefix, preview):
# 检查目录是否存在
ifnot os.path.isdir(directory):
print(f"Error: 目录不存在: {directory}")
return

    files = sorted(os.listdir(directory))
for i, filename inenumerate(files, 1):
        old_path = os.path.join(directory, filename)
        new_name = f"{prefix}_{i:03d}_{filename}"
        new_path = os.path.join(directory, new_name)

if preview:
print(f"[PREVIEW] Would rename: {filename} -> {new_name}")
else:
            os.rename(old_path, new_path)
print(f"Renamed: {filename} -> {new_name}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="批量重命名文件")
# 全部改成 -- 开头的可选参数
    parser.add_argument("--directory""-d", required=Truehelp="目标目录")
    parser.add_argument("--prefix""-p", default="file"help="文件名前缀")
    parser.add_argument("--preview""-v", action="store_true"help="预览模式")

    args = parser.parse_args()
    rename_files(args.directory, args.prefix, args.preview)

测试一下:

$ python rename_files.py --directory ./test_folder --preview
[PREVIEW] Would rename: a.txt -> file_001_a.txt
[PREVIEW] Would rename: b.txt -> file_002_b.txt
[PREVIEW] Would rename: c.txt -> file_003_c.txt

完美
现在预览模式正常工作了


但是,我还是觉得不爽

虽然问题解决了,但这个方案用起来还是有点麻烦
每次都要打 --directory,不能直接 ./test_folder 偷懒

而且我在想,有没有更好的方案
让我想起了之前听说的 click 库

正好趁机学习一下 click 是怎么处理这个问题的:

# rename_files_click.py
import os
import click

@click.command()
@click.argument("directory"type=click.Path(exists=True))
@click.option("--prefix""-p", default="file"help="文件名前缀")
@click.option("--preview""-v", is_flag=Truehelp="预览模式")
defrename_files(directory, prefix, preview):
"""批量重命名文件工具"""
    files = sorted(os.listdir(directory))
for i, filename inenumerate(files, 1):
        old_path = os.path.join(directory, filename)
        new_name = f"{prefix}_{i:03d}_{filename}"
        new_path = os.path.join(directory, new_name)

if preview:
            click.echo(f"[PREVIEW] Would rename: {filename} -> {new_name}")
else:
            os.rename(old_path, new_path)
            click.echo(f"Renamed: {filename} -> {new_name}")

if __name__ == "__main__":
    rename_files()

测试一下:

$ python rename_files_click.py ./test_folder --preview
[PREVIEW] Would rename: a.txt -> file_001_a.txt
[PREVIEW] Would rename: b.txt -> file_002_b.txt
[PREVIEW] Would rename: c.txt -> file_003_c.txt

$ python rename_files_click.py ./test_folder -v
[PREVIEW] Would rename: a.txt -> file_001_a.txt
[PREVIEW] Would rename: b.txt -> file_002_b.txt
[PREVIEW] Would rename: c.txt -> file_003_c.txt

$ python rename_files_click.py ./test_folder
Renamed: a.txt -> file_001_a.txt
Renamed: b.txt -> file_002_b.txt
Renamed: c.txt -> file_003_c.txt

**居然直接就能正常工作了
**

用 -v 或 --preview 都可以,预览模式完美生效
而且 click 自动生成的帮助信息也更清晰:

$ python rename_files_click.py --help
Usage: rename_files_click.py [OPTIONS] DIRECTORY
批量重命名文件工具

Options:
  -p, --prefix TEXT   文件名前缀
  -v, --preview       预览模式
  --help              Show this message and exit.

click 用了 @click.argument() 来处理位置参数,用 @click.option() 来处理可选参数
关键是,click 会自动区分这两种类型,不会出现 argparse 那种参数混淆的问题


完整的代码对比

最后,我把两个版本都保存了下来
这里是完整的可运行代码:

argparse 版本:

# rename_files_argparse.py
import os
import argparse

defrename_files(directory, prefix, preview):
"""批量重命名文件工具 - argparse 版本"""
ifnot os.path.isdir(directory):
print(f"Error: 目录不存在: {directory}")
return

    files = sorted(os.listdir(directory))
for i, filename inenumerate(files, 1):
        old_path = os.path.join(directory, filename)
        new_name = f"{prefix}_{i:03d}_{filename}"
        new_path = os.path.join(directory, new_name)

if preview:
print(f"[PREVIEW] Would rename: {filename} -> {new_name}")
else:
            os.rename(old_path, new_path)
print(f"Renamed: {filename} -> {new_name}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="批量重命名文件工具")
# 全部使用 -- 开头的可选参数,避免位置参数混淆
    parser.add_argument("--directory""-d", required=True
help="目标目录")
    parser.add_argument("--prefix""-p", default="file"
help="文件名前缀")
    parser.add_argument("--preview""-v", action="store_true"
help="预览模式")

    args = parser.parse_args()
    rename_files(args.directory, args.prefix, args.preview)

click 版本:

# rename_files_click.py
import os
import click

@click.command()
@click.argument("directory"type=click.Path(exists=True))
@click.option("--prefix""-p", default="file"help="文件名前缀")
@click.option("--preview""-v", is_flag=Truehelp="预览模式")
defrename_files(directory, prefix, preview):
"""批量重命名文件工具 - click 版本"""
    files = sorted(os.listdir(directory))
for i, filename inenumerate(files, 1):
        old_path = os.path.join(directory, filename)
        new_name = f"{prefix}_{i:03d}_{filename}"
        new_path = os.path.join(directory, new_name)

if preview:
            click.echo(f"[PREVIEW] Would rename: {filename} -> {new_name}")
else:
            os.rename(old_path, new_path)
            click.echo(f"Renamed: {filename} -> {new_name}")

if __name__ == "__main__":
    rename_files()

踩坑总结

这个坑踩下来,有几点经验教训:

  1. 1. argparse 的 positional argument 和 optional argument 容易混淆
    当有默认值的情况下,argparse 可能会把命令行参数的顺序搞错
    特别是 -v 这种短选项,很容易被误认为是 positional argument 的值
  2. 2. click 在参数解析上更智能
    click 用 @click.argument() 和 @click.option() 明确区分了两种参数类型,不会出现这种混淆
    而且 click 的类型检查(比如 type=click.Path(exists=True))也更实用
  3. 3. 调试时一定要打印 args
    这是最基本的,但很容易忽略
    如果一开始我就打印了 args 对象的内容,早就能发现 directory 的值被设置成了 -v,而不是目标目录
  4. 4. 不要过度依赖默认值
    虽然 argparse 的默认值机制很方便,但在 CLI 工具中,显式指定参数有时候更安全
    除非你的工具是给自己用的,否则用户体验很重要

最后的思考

现在我的 CLI 工具基本上都用 click 了
不是说 argparse 不好,它其实是标准库,不需要额外安装,但 click 在用户体验上确实更胜一筹

特别是:

  • • 自动生成的帮助信息更清晰
  • • 参数类型检查更方便
  • • 命令行解析逻辑更直观
  • • 支持子命令(group)

不过 argparse 也有它的优势:轻量(标准库)、文档丰富、如果你能搞清楚它的参数解析规则,用起来也很顺手

对于简单的小工具来说,两者都可以
但如果你要写一个稍微复杂一点的 CLI 工具,我推荐试试 click

至于这个重命名工具,最后朋友用的是 click 版本,他说用起来很顺手
我也比较满意,虽然中间踩了两个小时的坑,但最后学到了东西,也算值了


最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-04 03:10:41 HTTP/2.0 GET : https://f.mffb.com.cn/a/500093.html
  2. 运行时间 : 0.136442s [ 吞吐率:7.33req/s ] 内存消耗:4,790.98kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=3457d46d4e3721b4ca65828c72777e6b
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000707s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001067s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000385s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000300s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000657s ]
  6. SELECT * FROM `set` [ RunTime:0.000267s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000724s ]
  8. SELECT * FROM `article` WHERE `id` = 500093 LIMIT 1 [ RunTime:0.004570s ]
  9. UPDATE `article` SET `lasttime` = 1783105841 WHERE `id` = 500093 [ RunTime:0.012912s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000331s ]
  11. SELECT * FROM `article` WHERE `id` < 500093 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000611s ]
  12. SELECT * FROM `article` WHERE `id` > 500093 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000546s ]
  13. SELECT * FROM `article` WHERE `id` < 500093 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.008771s ]
  14. SELECT * FROM `article` WHERE `id` < 500093 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.030477s ]
  15. SELECT * FROM `article` WHERE `id` < 500093 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001647s ]
0.137964s