You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中从外部文件动态添加函数至字典供调用?

嘿,这个需求其实和Django自动识别视图的思路非常像,咱们可以通过动态模块导入+装饰器注册的组合来实现,完美解决跨文件的命令自动收集问题,下面是具体的实现步骤:

完整实现方案

1. 先做一个命令注册中心

首先创建一个command_registry.py文件,用来维护所有命令的字典,同时提供装饰器标记哪些函数是“命令”:

# command_registry.py
# 全局命令字典,key是命令名,value是对应的函数
commands = {}

def command(name=None):
    """装饰器:标记函数为命令,并注册到命令字典"""
    def decorator(func):
        # 如果用户没指定命令名,就用函数本身的名字
        cmd_name = name or func.__name__
        # 把函数注册到字典里
        commands[cmd_name] = func
        return func
    return decorator

2. 搭建commands文件夹结构

创建一个名为commands的文件夹,记得在里面放一个空的__init__.py文件(让Python把它识别为包)。然后你就可以在里面随便加.py文件了,比如:

示例1:greetings.py

# commands/greetings.py
from command_registry import command

# 用函数名作为命令名
@command()
def hello(name):
    return f"Hello, {name}!"

# 自定义命令名为say_hi
@command("say_hi")
def hi():
    return "Hi there!"

示例2:calculations.py(新增的文件)

# commands/calculations.py
from command_registry import command

@command()
def add(a, b):
    return int(a) + int(b)

@command()
def multiply(a, b):
    return int(a) * int(b)

3. 写一个自动加载器

接下来需要一个加载器,启动时自动导入commands文件夹下的所有.py文件,这样装饰器就能自动把函数注册到字典里。创建command_loader.py:

# command_loader.py
import os
import importlib

def load_commands():
    """自动导入commands文件夹下的所有模块"""
    # 获取commands文件夹的绝对路径
    commands_dir = os.path.join(os.path.dirname(__file__), "commands")
    
    # 遍历文件夹里的所有文件
    for filename in os.listdir(commands_dir):
        # 只处理.py文件,排除__init__.py和临时文件
        if filename.endswith(".py") and filename != "__init__.py":
            # 构造模块名(比如commands.greetings)
            module_name = f"commands.{filename[:-3]}"
            # 动态导入模块
            importlib.import_module(module_name)

4. 主程序调用逻辑

最后写主文件main.py,加载所有命令后,就可以接收用户输入来调用了:

# main.py
from command_registry import commands
from command_loader import load_commands

def main():
    # 启动时先加载所有命令
    load_commands()
    
    print("命令系统已启动,输入命令格式:命令名 参数1 参数2...(输入q退出)")
    while True:
        user_input = input("> ").strip()
        if user_input.lower() == "q":
            print("退出程序")
            break
        if not user_input:
            continue
        
        # 拆分命令名和参数
        parts = user_input.split()
        cmd_name = parts[0]
        args = parts[1:]
        
        # 执行命令
        if cmd_name in commands:
            try:
                result = commands[cmd_name](*args)
                print(f"✅ 执行结果:{result}")
            except TypeError as e:
                print(f"❌ 参数错误:{e}")
        else:
            print(f"❌ 未知命令,可用命令:{', '.join(commands.keys())}")

if __name__ == "__main__":
    main()

额外小贴士

  • 新增.py文件后,重启主程序就能自动加载新命令;如果想要热加载(不用重启),可以在主循环里定期调用load_commands(),但要注意在加载前清空commands字典,避免重复注册。
  • 命令函数的参数要和用户输入的参数数量匹配,或者可以用*args来处理可变参数,提升容错性。
  • 可以给装饰器加更多功能,比如命令描述、参数校验等,让系统更健壮。

内容的提问来源于stack exchange,提问作者WagnerAlbJr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:31:26