モジュール内モジュール(?)のインポート方法

Web系のサンプルコードでurllib2モジュールの利用をよく見かけるが、これはPython2系のモジュールで、Python3系ではurllibに変更・まとめられているため、そのまま記述するとエラーになってしまう。
そのため、コードを少し変更することになるのだが、そもそもモジュール内モジュール(という表現で合っているのかはわからず。urllib内のresponseモジュール等のことを指してます。)のimportやfromの動作が良く分かっていなかったようで、理解のために色々試したメモ。


目次

  1. 試したこと
  2. 結論

試したこと

いつもurllib2を使用しているコードを見かけると、import部分は以下の通り書き換えている。
■元コード(Python2系用)
import urllib2

上記をPython3系で実行すると以下ImportErrorとなる
Traceback (most recent call last):
  File "C:/path/to/sample.py", line 1, in <module>
    import urllib2
ImportError: No module named 'urllib2'

Process finished with exit code 1

■修正コード(Python3系用) ※ importするモジュールは必要なものを選択(他にresponse等有り)
from urllib import request

上記で困ったことは特別ないのだが、元々のPython2系用コードだと、コード内でのクラスへのアクセスは"urllib2.urlopen(req)"といった書き方になるのに対し、修正コードでは"request.urlopen(req)"といった書き方になり、このurlopenというメソッドが、コード内ではurllibモジュールであることが明示しないで記述される。

コード内でもurllibモジュール内の(request内の)urlopenであることを明示させたいと思い、以下のimport文に変更してみるとエラーになってしまった。urllibをインポートしただけではrequestモジュールにアクセスできないらしい。

import urllib
type(urllib.request)

Traceback (most recent call last):
  File "C:/path/to/sample.py", line 2, in 
    type(urllib.request)
AttributeError: module 'urllib' has no attribute 'request'

Process finished with exit code 1


dir()でも確認してみた。確かにrequestやresponseがない。
import urllib
dir(urllib)

[   '__builtins__',
    '__cached__',
    '__doc__',
    '__file__',
    '__loader__',
    '__name__',
    '__package__',
    '__path__',
    '__spec__']
※ そのままprintすると見づらいのでpprintを用いた出力結果

結論

ごにょごにょ試したが、コード内でもurllibモジュール内の(request内の)urlopenであることを明示させたい場合は、以下の通り記述すればいい。これで"urllib.request.urlopen(req)"といったコードが書ける。
import urllib.request

dir()の結果も以下の通り。
import urllib.request
dir(urllib)

[   '__builtins__',
    '__cached__',
    '__doc__',
    '__file__',
    '__loader__',
    '__name__',
    '__package__',
    '__path__',
    '__spec__',
    'error',
    'parse',
    'request',
    'response']
※ urllib.requestをインポートしただけでresponse等もインポートされる

コメント

このブログの人気の投稿

Python SQLite スレッド間でコネクションの使いまわしは出来ない

slackでgeneralの投稿を全削除する

Google location history(JSON形式)をCSVファイルにする