2

因此,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 ';'

同样,我知道有其他方法可以做到这一点。然而,这能做到吗?装饰器可以始终尊重原始函数的签名,还是有时或根本不尊重?如果这是可能的,那么它是异端吗?为什么?

4

1 回答 1

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 +
                ';')
    
于 2012-10-26T23:50:12.980 回答