编写python闭包的更好方法? [关闭]

Posted

技术标签:

【中文标题】编写python闭包的更好方法? [关闭]【英文标题】:A better way to write python closures? [closed] 【发布时间】:2013-05-24 00:03:42 【问题描述】:

我的问题可以用简单的是或否来回答:

是的,italic 的“闭包风格”是写 python 的更好方式 闭包——换句话说——italic 的“闭包符号”不会中断并且 没有任何警告

不,italic 的闭包有问题,bold 的“闭包符号”是 唯一的出路

以防万一,如果有人想知道“怎么了”,错了为什么“他”不 使用标准的闭包——标准的形式,让我想逃跑。

def example():

    # The standard X_x closure...
    #
    def bold(predecessor):
        def successor():
            return "<bold/>" + predecessor() + "</bold>"
        return successor

    # ...this looks sooo much better ^.^
    #
    def italic(predecessor):
        x = predecessor
        def successor():
            return "<italic/>" + x() + "</italic>"
        return successor

    def underline(predecessor):
        x = predecessor
        def successor():
            return "<underline/>" + x() + "</underline>"
        return successor

    @italic
    @bold
    @underline
    def trademark():
        return "This trademark cant be changed."

    print(trademark())
    #example() prints <italic/><bold/><underline/>This trademark cant be changed.</underline></bold</italic>

【问题讨论】:

我怀疑上面有一个真正的问题,但我厌倦了阅读你的咆哮并放弃了。你想知道什么,伙计? 如果你只关注事实而不被社论cmet所困,你可能会得到更好、更有礼貌的回应。只是说。 我不知道为什么你提到的案例不同。除了分配一个多余的临时变量(成本不是很高)之外,它们是相同的。 "&lt;italic/&gt;" + x() + "&lt;/italic&gt;" 是一些看起来很奇怪的 XML... 更重要的是,xpredecessor 都在italic 的本地范围内,因此在为successor 生成closure 时将被完全相同地对待。不然怎么可能? 【参考方案1】:

当然可以:

def italic(predecessor):
    x = predecessor
    def successor():
        return "<italic/>" + x() + "</italic>"
    return successor

就像你可以做的那样:

def italic(predecessor):
    x = predecessor
    x2 = x
    def successor():
        return "<italic/>" + x2() + "</italic>"
    return successor

def italic(predecessor):
    x = predecessor
    x2 = x
    x3 = x2
    def successor():
        return "<italic/>" + x3() + "</italic>"
    return successor

但是你为什么想要呢?


编写装饰器的最佳方式是使用functools.wraps

from functools import wraps

def italic(f):
    @wraps(f)
    def decorated():
        return "<italic/>" + f() + "</italic>"
    return decorated

但如果你真的想与众不同:

import functools

def italic(f):
    return functools.update_wrapper(lambda: "<italic/>" + f() + "</italic>", f)

【讨论】:

应该指出使用 + 构建字符串是 Python 中的一种反模式。 @StevenRumbalski 什么?它不是。现在,通过非常大或无限数量的连接来累积字符串存在性能问题,应该避免,但+ 是连接字符串的惯用方式。 可以说,使用str.format() 可以更轻松地完成此操作,但是是的,+ 加入一些这样的字符串是合法的。 @delnan:OP 的示例扩展为 "&lt;bold/&gt;" + ("&lt;italic/&gt;" + ("&lt;underline/&gt;" + predecessor() + "&lt;/underline&gt;") + "&lt;/italic&gt;") + "&lt;/bold&gt;"。我认为这太过分了。 FWIW,我经常使用+来加入一些价值观,所以我并不完全反对这个概念。 @StevenRumbalski:因此,使用+ 构建字符串并不是一种反模式(我认为这与 Lattyware 解释的不相关),但使用字符串构建 html 并不好想法(我同意)?

以上是关于编写python闭包的更好方法? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

什么时候使用闭包? [关闭]

python中的dict() vs 哪个更好? [关闭]

开发 GUI 的更好的语言? [关闭]

更好地线程化代码以减少计算时间的方法[关闭]

这是在 JavaScript 中形成闭包的正确方法吗? [关闭]

更好的网络框架? [关闭]