使用通用函数转换函数的所有输入参数

时间:2014-01-16 15:18:00

标签: python

我正在编写一个从数据库中获取用户并返回用户对象列表的函数。 功能签名如下:

def select_users(self,userid,firstname,lastname,emailid,tenants,groups):
    result = self.authservice.select_users(userid,firstname,lastname,emailid,tenants,groups)

在此函数中,我调用select_users对象的authservice方法,该方法将返回自定义用户对象的列表。但是,如果任何输入参数具有''值,则必须将其转换为None,因为self.authservice.select_users无法处理空字符串。我可以检查每个元素值,如果它是空的,则将其转换为None,但我希望它是通用的,可重用的。如果我可以写一个不同的函数,它可以给我更新的输入参数列表,这将是非常有帮助的。请让我知道我该怎么做?

4 个答案:

答案 0 :(得分:2)

邪恶的方式:

def select_users(self, *args):
    new_args = [(None if arg == '' else arg) for arg in args]
    result = self.authservice.select_users(*new_args)

装饰器解决方案也很邪恶:更改函数参数以备不时编写几个函数调用似乎不是一个好主意。

在现实生活中,我会明确地说:

def never_blank(s):
    return None if s == '' else s

def select_users(self, userid,firstname,lastname,emailid,tenants,groups):
   result = self.authservice.select_users(userid,never_blank(firstname),never_blank(lastname),emailid,
                          never_blank(tenants),groups)

乏味?当然。清洁?是的。将来会咬你的屁股吗?不。

答案 1 :(得分:2)

我会写一个通用装饰器,像这样

def convert_empty_to_none(func):
    def inner_function(*args, **kwargs):
        args = (None if item == "" else item for item in args)
        kwargs = {k:(None if v == "" else v) for k, v in kwargs.items()}
        return func(*args, **kwargs)
    return inner_function

@convert_empty_to_none
def test_function(a, b, c):
    print a, b, c

test_function("", "", "")

<强>输出

None None None

答案 2 :(得分:1)

创建一个函数并像函数类型装饰器一样使用它

def sanitize(func):
    def handler(*args, **kwargs):
        args = (e if e != '' else None for e in args)
        kwargs = {k:(v if v != '' else None) for k, v in kwargs.items()}
        return func(*args, **kwargs)
    return handler

@sanitize
def select_users(self,userid,firstname,lastname,emailid,tenants,groups):
    result = self.authservice.select_users(userid,firstname,lastname,emailid,tenants,groups)

<强>了好处

  1. 您无需修改​​签名
  2. 调用者仍然可以清楚地了解函数所需的参数
  3. 通用,可用于任何函数调用
  4. 是装饰者,因此可以很容易地以非侵入方式使用

答案 3 :(得分:1)

您可以使用装饰器创建一个通用包装器,用None替换每个空字符串。

def none_for_empty_string(func):

    def wrapper(*args, **kwargs):

        args = tuple(arg if arg != '' else None for arg in args)
        kwargs = {k : v if v != '' else None for k, v in kwargs.iteritems()}
        return func(*args, **kwargs)

    return wrapper

@none_for_empty_string
def select_users(self,userid,firstname,lastname,emailid,tenants,groups):
    ...