14 votes

Renommer les fonctions en préservant la rétrocompatibilité

Je refactorise mon ancien code et je veux changer les noms des fonctions en accord avec pep8. Mais je veux maintenir la rétrocompatibilité avec les anciennes parties du système (un remaniement complet du projet est impossible car les noms des fonctions font partie de l'API et certains utilisateurs utilisent l'ancien code client).

Exemple simple, ancien code :

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

Nouveau :

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

Mais les deux fonctions devraient fonctionner :

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

Je pense à :

def helloFunc(name):
    hello_func(name)

mais je n'aime pas ça (dans le projet, il y a environ 50 fonctions, et ça fera un peu désordre, je pense).

Quelle est la meilleure façon de procéder (sans duplication de la source) ? Est-il possible de créer un décorateur universel ?

Merci.

11voto

mgilson Points 92954

Je pense que pour l'instant, le plus simple est de créer une nouvelle référence à l'ancien objet fonction :

def helloFunc():
    pass

hello_func = helloFunc

Bien sûr, ce serait probablement plus légèrement plus propre si vous changez le nom de la fonction actuelle en hello_func et a ensuite créé l'alias en tant que :

helloFunc = hello_func

C'est toujours un peu désordonné car cela encombre inutilement l'espace de noms de votre module. Pour contourner ce problème, vous pouvez également avoir un sous-module qui fournit ces "alias". Ensuite, pour vos utilisateurs, il suffirait de modifier les paramètres suivants import module à import module.submodule as module mais vous n'encombrez pas l'espace de noms de votre module.

Vous pourriez même utiliser inspect pour faire quelque chose comme cela automatiquement (non testé) :

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)

7voto

glglgl Points 35668

Bien que les autres réponses soient certainement vraies, il pourrait être utile de renommer la fonction au nouveau nom et de créer une ancienne fonction qui émet un avertissement :

def func_new(a):
    do_stuff()

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

4voto

Rostyslav Dzinko Points 10667

Vous pouvez lier votre objet de fonction à un autre nom dans l'espace de noms de votre module, par ex :

def funcOld(a):
    return a

func_new = funcOld

2voto

gustafbstrom Points 755

Comme votre question ressemble beaucoup à une dépréciation ou autre, j'aimerais recommander fortement l'utilisation de décorateurs pour un code plus propre. En fait, quelqu'un dans un autre fil a déjà a créé ceci pour vous .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X