繁体   English   中英

在部署的 Python 模块中重命名方法参数的最佳实践

[英]Best practice to rename a method parameter in a deployed Python module

假设我使用一些方法foo()维护一个 Python 模块:

def foo(BarArg=None, AnotherArg=False):
   return True

但是现在我对我的参数名称的 PascalCase 不满意,并且想这样重命名它们:

def foo(bar_arg=None, another_arg=False):
   ...

如何在不破坏现有客户端代码的情况下引入此更改?

我真的不想要弃用警告(但也许这是最佳实践),并且也非常想保留我的函数名称......

目前, **kwargs加上一些输入验证逻辑是唯一想到的解决方案,但它似乎是错误的方向。

您可以使用装饰器工厂来拦截对不正确参数的任何使用:

def re_arg(kwarg_map):
    def decorator(func): 
        def wrapped(*args, **kwargs):
            new_kwargs = {}
            for k, v in kwargs.items():
                if k in kwarg_map:
                    print(f"DEPRECATION WARNING: keyword argument '{k}' is no longer valid. Use '{kwarg_map[k]}' instead.")
                new_kwargs[kwarg_map.get(k, k)] = v
            return func(*args, **new_kwargs)
        return wrapped
    return decorator


# change your kwarg names as desired, and pass the kwarg re-mapping to the decorator factory
@re_arg({"BarArg": "bar_arg", "AnotherArg": "another_arg"})
def foo(bar_arg=None, another_arg=False):
    return True

演示:

In [7]: foo(BarArg="hello")
DEPRECATION WARNING: keyword argument 'BarArg' is no longer valid. Use 'bar_arg' instead.
Out[7]: True

In [8]: foo(AnotherArg="hello")
DEPRECATION WARNING: keyword argument 'AnotherArg' is no longer valid. Use 'another_arg' instead.
Out[8]: True

In [9]: foo(x="hello")  # still errors out on invalid kwargs
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [9], line 1
----> 1 foo(x="hello")

Cell In [4], line 9, in re_arg.<locals>.wrapped(**kwargs)
      7         print(f"DEPRECATION WARNING: keyword argument '{k}' is no longer valid. Use '{kwarg_map[k]}' instead.")
      8     new_kwargs[kwarg_map.get(k, k)] = v
----> 9 return func(**new_kwargs)

TypeError: foo() got an unexpected keyword argument 'x'

In [10]: foo(another_arg="hello")  # no warning if you pass a correct arg (`bar_arg` has a default so it doesn't show up in `new_kwargs`.
Out[10]: True

In [11]: foo(BarArg="world", AnotherArg="hello")
DEPRECATION WARNING: keyword argument 'BarArg' is no longer valid. Use 'bar_arg' instead.
DEPRECATION WARNING: keyword argument 'AnotherArg' is no longer valid. Use 'another_arg' instead.
Out[11]: True

您可能会非常喜欢,将旧的 kwargs 与新的 kwargs 一起留下,检查签名,提取旧的 kwargs 并动态构建kwarg_map ,但在我看来,这可能需要做更多的工作,可能不会有太大的收获,所以我将“把它作为练习留给读者”。

另一种解决方案是简单地添加一个new_foo function,将旧的foo实现转移过来,然后使用上面显示的 kwarg 重新映射简单地从foo调用new_foo ,并带有弃用警告,但我认为这比必须维护一个更干净一堆存根。

您可能还想查看deprecation库: https://pypi.org/project/deprecation/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM