Pythonの辞書をドットでアクセス [Main] 「どう書く?org」(ベータ版)を公開しました

Pythonの辞書をドットでアクセス[Python(18)]大きなテーブルへのForeignKeyにはraw_id_admin=True

Pythonで関数名を安全に変更する

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

フィードバック

by Dubhead | 2007年10月17日 16:39

deprecatedをデコレイタにすると更によし?

--- 古い方の関数をもう使わない場合には単純に@deprecatedとデコレートするだけでOKのはずです。そういうつもりで作ったので。

by しみずかわ | 2007年10月31日 15:21

Pythonライブラリの "3.20 warnings -- 警告の制御" を使うのが良いと思います。

ご意見・ご感想をお送りください(フィードバック)

(フィードバックはメールで送信され、基本的に表示されませんが、内容によっては公開させていただくこともございます。ご了承ください。Your comment doesn't appear the page immediately. If the comment has value to other people, it will be put on the page or subsequent entries. Thank you.)

上の情報は、いずれも未記入でかまいません。 All of above questions are optional.