【问题标题】:Renaming of functions with preservation of backward compatibility在保留向后兼容性的情况下重命名函数
【发布时间】:2012-08-12 19:07:19
【问题描述】:

我重构了我的旧代码,并想根据 pep8 更改函数名称。但我想保持与系统旧部分的向后兼容性(完全重构项目是不可能的,因为函数名称是 API 的一部分,并且一些用户使用旧的客户端代码)。

简单示例,旧代码:

def helloFunc(name):
    print 'hello %s' % name

新:

def hello_func(name):
    print 'hello %s' % name

但这两个功能都应该可以工作:

>>hello_func('Alex')
>>'hello Alex'
>>helloFunc('Alf')
>>'hello Alf'

我在想:

def helloFunc(name):
    hello_func(name)

,但我不喜欢它(在项目中大约有 50 个函数,我认为它看起来会很乱)。

最好的方法是什么(不包括重复课程)?是否有可能创建一个通用的装饰器?

谢谢。

【问题讨论】:

    标签: python refactoring


    【解决方案1】:

    由于您的问题听起来很像弃用或类似的问题,我强烈建议您使用装饰器来获得更简洁的代码。事实上,另一个线程中的某人已经created this for you

    【讨论】:

      【解决方案2】:

      虽然其他答案绝对正确,但将函数重命名为新名称并创建一个发出警告的旧名称可能会很有用:

      def func_new(a):
          do_stuff()
      
      def funcOld(a):
          import warnings
          warnings.warn("funcOld should not be called any longer.")
          return func_new(a)
      

      【讨论】:

      • 更好的是,使用warnings.warn('description', DeprecationWarning) 明确指出此调用转换已弃用
      【解决方案3】:

      我认为目前,最简单的方法是创建对旧函数对象的新引用:

      def helloFunc():
          pass
      
      hello_func = helloFunc
      

      当然,如果您将实际函数的名称更改为hello_func,然后将别名创建为:

      ,它可能会更稍微更干净
      helloFunc = hello_func
      

      这仍然有点混乱,因为它不必要地混淆了您的模块命名空间。为了解决这个问题,您还可以有一个提供这些“别名”的子模块。然后,对于您的用户来说,就像将 import module 更改为 import module.submodule as module 一样简单,但您不会弄乱您的模块命名空间。

      您甚至可以使用 inspect 自动执行类似的操作(未经测试):

      import inspect
      import re
      def underscore_to_camel(modinput,modadd):
          """
             Find all functions in modinput and add them to modadd.  
             In modadd, all the functions will be converted from name_with_underscore
             to camelCase
          """
          functions = inspect.getmembers(modinput,inspect.isfunction)
          for f in functions:
              camel_name = re.sub(r'_.',lambda x: x.group()[1].upper(),f.__name__)
              setattr(modadd,camel_name,f)
      

      【讨论】:

      • @vlad -- 我添加了一个函数,我认为它会自动将模块 modinput 中的 function_with_underscores 添加到 modadd 作为 functionWithUnderscores (但它不适用于 @ 987654332@ 函数,因为它们没有可检查的名称(AFAIK)
      • 感谢setattr!显然是这样的。
      【解决方案4】:

      您可以将函数对象绑定到模块命名空间中的另一个名称,例如:

      def funcOld(a):
          return a
      
      func_new = funcOld
      

      【讨论】:

        猜你喜欢
        • 2016-10-29
        • 1970-01-01
        • 1970-01-01
        • 2011-11-10
        • 2014-08-10
        • 2020-06-04
        • 1970-01-01
        • 1970-01-01
        • 2019-08-29
        相关资源
        最近更新 更多