重构功能界面

时间:2016-02-16 20:04:24

标签: python

我有一个后端库的功能接口,如下所示:

def func1(*pars, **kwargs):
    be = Backend(...)
    result = be.do_something(...)
    result = adapt(result)
    ...
    return result

后端接口已经改变了一点(需要一个新的config参数),所以现在我需要重构为:

def func1(config, *pars, **kwargs):
    be = Backend(config, ...)
    result = be.do_something(...)
    result = adapt(result)
    ...
    return result

我需要更改界面中的所有函数以接受并传递这个新的config参数。您是否有更好的建议如何进行此重构,以便:

  • 最小化变更
  • 允许更容易的将来重构,后端可能需要更多参数

一般来说,你有没有关于如何在python中提供干净的功能接口的一些指示?

1 个答案:

答案 0 :(得分:0)

嗯,我认为你无论如何都需要更新你的每个功能,但是你可以通过一种方式来实现,这将使未来的更新更容易。考虑以下装饰者:

def backend_wrapper(function):
    def _wrapper(arg1, arg2, arg3, *pargs, **kwargs):
        backend_args = (arg1, arg2, arg3)
        return function(backend_args, *pargs, **kwargs)
    return _wrapper

如果您更新所有函数,请使用此装饰器并接受新的位置参数backend_args,然后您可以将所有未来更新应用于装饰器。

class Backend:
    def __init__(self, *args):
        print 'Backend args: {}'.format(args)

@backend_wrapper
def func1(backend_args, *pargs, **kwargs):
    be = Backend(*backend_args)
    print 'Positional args: {}'.format(pargs)
    print 'Keyword args: {}'.format(kwargs)

func1('arg1', 'arg2', 'arg3', 'parg1', kwarg1='kwarg1')
# Backend args: ('arg1', 'arg2', 'arg3')
# Positional args: ('parg1',)
# Keyword args: {'kwarg1': 'kwarg1'}

所以,现在如果我们将装饰器更改为:

def backend_wrapper(function):
    def _wrapper(arg1, *pargs, **kwargs):
        backend_args = (arg1,)
        return function(backend_args, *pargs, **kwargs)
    return _wrapper

然后,func1仍将按预期运作。

func1('arg1', 'parg1', kwarg1='kwarg1')
# Backend args: ('arg1',)
# Positional args: ('parg1',)
# Keyword args: {'kwarg1': 'kwarg1'}

此问题在于您仍然需要更新函数调用以传递新参数。除非您能够制作backend_args全局变量,否则我无法找到解决方法。但是,如果是这种情况,您可以使用以下内容:

class Backend:
    def __init__(self, *args):
        print 'Backend args: {}'.format(args)

def backendFactory(*backend_args):
    def _wrapper():
        return Backend(*backend_args)
    return _wrapper

def func1(*pargs, **kwargs):
    be = BackendFactory()
    print 'Positional args: {}'.format(pargs)
    print 'Keyword args: {}'.format(kwargs)

BackendFactory = backendFactory('arg1', 'arg2', 'arg3')
func1('parg1', kwarg1='kwarg1')
# Backend args: ('arg1', 'arg2', 'arg3')
# Positional args: ('parg1',)
# Keyword args: {'kwarg1': 'kwarg1'}

这创建了一个全局变量BackendFactory,它以类似于类的方式运行,除了它存储实例化变量。请注意,这是混乱和危险的,因为它会回复您定义一个全局变量,然后在您的函数中使用。