Pythonのような動的な言語では、Javaのように「メソッドの名前を呼び出しも含めて変更」というリファクタリングが簡単ではありません。整合性をチェックするフェーズがないので、不用意に名前を変更すると実行時に「そんな名前の関数はない」と怒られてしまいます。
そこで「一度deprecated(非推奨)にする」という方法を考えました。
まず下のようにfooという関数と、それを読んでいるcallerという関数を作りました。今からこのfooをbarという名前に変更したいと思います。
しかし、実際にはcallerは大量のソースの中に散らばっているものとします。
>>> def foo():
return 1
>>> def caller():
return foo()
fooの名前を変更します。ここではbar = fooとしていますが、もちろんdef foo...をdef bar...に書き換えるのでもOKです。実際は後者になるでしょう。
そして、fooという名前で改めて警告メッセージを出してbarを呼ぶ関数を定義します。
>>> bar = foo
>>> def foo():
import inspect
print "'foo' is deprecated: called from", inspect.stack()[1][3]
return bar()
こうすると、うっかりcallerの中のfooの呼び出しをbarの呼び出しに変え忘れても:
>>> caller()
'foo' is deprecated: called from caller
1
変える値は変わらず、警告メッセージだけが表示されるようになります。警告は今はprintで出していますが、ログに出すなりなんなりするといいと思います。
追記:
毎回こういうことを書くのも面倒なので関数にまとめました。
>>> def deprecated(f):
def deprecated_func(*args, **kw):
import inspect
print "'%s' is deprecated:" % f.func_name,
print "line %s in '%s'" % tuple(inspect.stack()[1][2:4])
return f(*args, **kw)
return deprecated_func
>>> def nibai(x):
return x * 2
>>> def foo():
print nibai(10)
print nibai(20)
>>> foo()
20
40
>>> nibai = deprecated(nibai)
>>> foo()
'nibai' is deprecated: line 2 in 'foo'
20
'nibai' is deprecated: line 3 in 'foo'
40