PyCharm 将 Python 函数中的代码提取到嵌套函数中

Have PyCharm extract code in a Python function to a nested function

我有PyCharm2017.3将一个顶层函数中的一些代码提取到另一个顶层函数中,效果很好。

但是,有时我不想将提取的函数放在顶层,而是应该将其嵌套在现有函数中。基本原理是重用仅在函数内部使用但多次使用的代码。我认为这个 "sub-function" 最好不能在原始函数之外访问。

我该怎么做?我在重构对话框中没有看到任何选项。

例子

a) 原代码:

def foo():
    a = ''
    if a == '':
        b = 'empty'
    else:
        b = 'not empty'
    return b

b) 提取的作用:

def foo():
    a = ''
    b = bar(a)
    return b


def bar(a):
    if a == '':
        b = 'empty'
    else:
        b = 'not empty'
    return b

c) 我想要的东西:

def foo():
    def bar():
        if a == '':
            b = 'empty'
        else:
            b = 'not empty'
        return b

    a = ''
    b = bar(a)
    return b

我知道 barb 会影响 foob 除非在此过程中重命名。我还考虑过不返回或请求 b 并仅在 bar.

内修改它来完全接受阴影

如果我想要的东西出于任何原因不是一件好事,也请提示我。

隔离函数边界被认为是一种很好的做法:将数据作为参数获取,并将数据作为 return 值输出,并尽可能减少副作用。也就是说,在某些特殊情况下您会违反此规则;他们中的许多人在使用 closures 时。 Python 中的闭包不像 Javascript 中那样惯用 - 我个人认为这很好,但很多人不同意。

有一个地方闭包在 Python 中是绝对惯用的:装饰器。对于您使用闭包以避免使用全局变量并提供某种形式的数据隐藏的其他情况,Python 中还有其他选择。尽管有些人提倡在只有一个方法时使用闭包而不是 class,但将普通函数与 functools.partial 结合使用会更好。

这是我对为什么 Pycharm 中没有这样的功能的猜测:我们几乎从不在 Python 中这样做,相反我们倾向于将函数签名保持为 foo(x) 甚至当我们可以从封闭范围中获取 x 时。该死,在 Python 中,我们的方法显式接收 self,而大多数语言都有隐式 this。如果您以这种方式编写代码,那么 Pycharm 已经完成了重构时所需的一切:它修复了剪切和粘贴时的缩进。

如果你发现自己经常进行这种重构,我猜你来自一种闭包更惯用的语言,如 Javascript 或 Lisp。

所以我的观点是:这个 "nested to global" 或 "global to nested" 函数重构特性在 Pycharm 中不存在,因为依赖于封闭作用域的嵌套函数在 [=31= 中不是惯用的] 除非闭包 - 甚至闭包在装饰器之外也不是那么惯用。

如果您足够关心,请在 their issue tracker or upvote some related tickets like #PY-12802 and #PY-2701 填写功能请求 - 如您所见,可能由于上述原因,这些功能并未引起太多关注。