home changes contents help options

264:互換性を保ったままライブラリ名を変える

次の内容の oldmodule.py が存在し、これを newmodule.py に名前を変えようとしている、とします。

import re

_search_hello = re.compile(u'hello')
def search_hello(s):
    return _search_hello.search(s)

まずは次のようにします。

# oldmodule.py を newmodule.py にリネーム。内容は変えない。
import re

_search_hello = re.compile(u'hello')
def search_hello(s):
    return _search_hello.search(s)


# つぎのように oldmodule.py を作り直す
from newmodule import *

この時点で、 oldmodule を使用する古いコードは正常動作するはずです。異常があるときには、次の点に注意して oldmodule.py の修正を行ってください。

たとえば、次のコードは正常動作しません。

>>> from oldmodule import *
>>> _search_hello.match('hello') # NG 。外部使用を意図していない変数の直接使用
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '_search_hello' is not defined
>>>
>>> search_hello('hello') # これは OK
<_sre.SRE_Match object at 0x00A53D40>

「from oldmodule import *」でインポートされない変数があるというのは、モジュール作者にその変数をモジュール外で使用して欲しくないという意図があるためです。理想論を持ち出してしまうと「古いモジュールを使用しているコードが規約を守っていない。こちらを直すべき。」となります。

とはいえ、実際はそううまくはいかないもので、古いモジュールを使用しているコードに手をつけられないこともあるでしょう。この場合、すべての値をインポートする必要があります。次のようにするとよいでしょう。

# つぎのように oldmodule.py を作り直す
import newmodule
globals().update(newmodule.__dict__)

この後は、古いモジュールからもともとあった機能がなくならないように、新旧モジュールを修正していくようにしてください。

参考