Python中如何实现函数依赖的功能可扩展?

想实现的目标是,主函数 f_a(), 是个解析帧的函数,当前把不同帧格式的解析函数都写死在了主函数里。当然也可以做成 list 当参数传入。但使用这个函数就很奇怪,每次都要传这个 list,感觉这个接口不好。
想问下有什么好的代码结构,可以解决这个问题。最好是能库函数和用户函数分离的结构。
Python中如何实现函数依赖的功能可扩展?

3 回复

在Python里搞函数依赖扩展,我一般用装饰器配合注册表模式。直接上代码:

from functools import wraps
from typing import Dict, Callable, Any

class DependencyRegistry:
    def __init__(self):
        self._dependencies: Dict[str, Callable] = {}
        self._instances: Dict[str, Any] = {}
    
    def register(self, name: str):
        def decorator(func):
            self._dependencies[name] = func
            @wraps(func)
            def wrapper(*args, **kwargs):
                if name not in self._instances:
                    self._instances[name] = func(*args, **kwargs)
                return self._instances[name]
            return wrapper
        return decorator
    
    def get(self, name: str):
        if name not in self._instances:
            if name in self._dependencies:
                self._instances[name] = self._dependencies[name]()
            else:
                raise KeyError(f"Dependency '{name}' not registered")
        return self._instances[name]

# 全局注册表实例
registry = DependencyRegistry()

# 使用示例
@registry.register("database")
def create_db_connection():
    print("Creating database connection...")
    return {"db": "postgresql://localhost/mydb"}

@registry.register("cache")
def create_cache_client():
    print("Creating cache client...")
    return {"cache": "redis://localhost"}

@registry.register("service")
def create_service():
    # 依赖注入:获取已注册的依赖
    db = registry.get("database")
    cache = registry.get("cache")
    print(f"Creating service with db={db}, cache={cache}")
    return {"service": "main_service", "deps": [db, cache]}

# 测试
if __name__ == "__main__":
    # 获取service时会自动创建其依赖
    service = registry.get("service")
    print(f"Service: {service}")
    
    # 再次获取会使用缓存实例
    service2 = registry.get("service")
    print(f"Same instance: {service is service2}")

这个实现的核心思路是:

  1. DependencyRegistry类管理所有依赖的注册和实例化
  2. @registry.register()装饰器用来声明依赖项
  3. registry.get()方法获取依赖时,如果还没实例化就创建,实现了懒加载
  4. 依赖之间可以相互引用,create_service函数里通过registry.get()获取它需要的databasecache

这样扩展起来很方便,要加新依赖就再加个@registry.register装饰的函数。依赖关系在函数内部通过registry.get()显式声明,比隐式导入更清晰。

用装饰器注册依赖项,用的时候直接get就行。


方式很多:
<br>class X:<br> def __init__(参数):<br> pass<br><br>def f_a(x):<br> if isinstance(x, X):<br> pass<br> else:<br> raise XXXXError('参数类型不对')<br>f_a(X(xx,yy,zzz))<br><br>def f_a(*args):<br> pass<br><br>f_a(*a_list)<br><br><br>def f_a(**kwargs):<br> pass<br><br>f_a(x=xx,y=yy)<br><br>

说实话没看懂你的需求是啥

回到顶部