python 2.7中的string_builder装饰器 - 怎么做,我应该怎么做?

时间:2012-10-26 23:47:13

标签: python python-2.7 decorator stringbuilder

因此,Python没有提供明确的C#或Java风格的StringBuilder类。 注意,我对Python有点新意,所以我不确定我的想法是不是很好。

假设我想要一个将迭代器连接在一起的装饰器(如果可能的话)。这个特定的例子可以不同的方式实现,但我可以想到其他用例。所以...

@string_builder
def build_insert_statement(table_name, col_names, values, where_clause):
    yield 'insert into '
    yield table_name
    yield ' ( '
    yield ', '.join(col_names)
    yield ' ) values ( '
    yield ', '.join(values)
    yield ' ) where '
    yield where_clause
    yield ';'

同样,我知道有其他方法可以做到这一点。但是,这可以吗?装饰者是否总是尊重原始功能的签名,或者只是有时或根本不尊重?如果这是可能的,那么这是异端邪说吗?为什么呢?

1 个答案:

答案 0 :(得分:2)

string_builder的以下定义应该有效:

from functools import wraps

def string_builder(func):
    @wraps(func)
    def wrapped(*args, **kwargs):
        return ''.join(func(*args, **kwargs))
    return wrapped

使用问题中定义的函数string_builder作为装饰器:

>>> build_insert_statement('foo', ['bar'], ['1'], 'baz')
'insert into foo ( bar ) values ( 1 ) where baz;'

请注意,使用[functools.wraps] [1]不是必需的,但这是一个好习惯,因为没有它,装饰后的函数名称(build_insert_statement.__name__)将被“包裹”而不是“ build_insert_statement”。

所以有可能,这是个好主意吗?

不是你的例子,但你说你有其他用例。像这样的装饰者不是异端,但你不应该过度使用装饰器,因为它可能会掩盖实现。

如果您只是担心线路长度,请考虑以下其中一种选择:

  • 在列表中使用''.join()

    def build_insert_statement(table_name, col_names, values, where_clause):
        return ''.join(['insert into ',
                        table_name,
                        ' ( ',
                        ', '.join(col_names),
                        ' ) values ( ',
                        ', '.join(values),
                        ' ) where ',
                        where_clause,
                        ';'])
    
  • 将字符串与+

    组合在一起
    def build_insert_statement(table_name, col_names, values, where_clause):
        return ('insert into ' +
                table_name +
                ' ( ' +
                ', '.join(col_names) +
                ' ) values ( ' +
                ', '.join(values) +
                ' ) where ' +
                where_clause +
                ';')