コードの断片に違いがあるかどうか疑問に思います
from urllib import request
そしてその断片
import urllib.request
あるいはそれらが交換可能であるならば。それらが互換性がある場合、「標準」/「推奨」構文はどれですか(ある場合)。
ありがとうございます。
参照するときにインポートにアクセスする方法によって異なります。
from urllib import request
# access request directly.
mine = request()
import urllib.request
# used as urllib.request
mine = urllib.request()
簡単にするためにインポートするときや、組み込みのマスキングを避けるために、自分自身で別名を付けることもできます。
from os import open as open_
# lets you use os.open without destroying the
# built in open() which returns file handles.
多くの人がすでにimport
とfrom
について説明しているので、実際の違いがあるところで、もう少し詳しく説明したいと思います。
まず最初に、基本的なimport文が何をするのかを正確に説明しましょう。
import X
モジュール
X
をインポートし、現在のネームスペースにそのモジュールへの参照を作成します。次に、モジュールの内部から特定の属性またはメソッドにアクセスするための完成したモジュールパスを定義する必要があります(例:X.name
またはX.attribute
)。
from X import *
モジュール
X
をインポートし、現在のネームスペースでそのモジュールによって定義されているすべてのパブリックオブジェクト(つまり、_
で始まる名前を持たないすべてのもの)への参照を作成します。あるいは、言い換えれば、このステートメントを実行した後で、単純な(修飾されていない)名前を使用して、モジュール
X
で定義されているものを参照することができます。しかしX
自体は定義されていないので、X.name
は機能しません。name
がすでに定義されている場合は、新しいバージョンに置き換えられます。X
の名前が他のオブジェクトを指すように変更されても、モジュールは気付かないでしょう。これにより、モジュールからのすべての名前がローカル名前空間で使用可能になります。
import X.Y
を実行するとどうなるか見てみましょう。
>>> import sys
>>> import os.path
os
およびsys.modules
という名前のos.path
を確認します。
>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
globals()
およびlocals()
名前空間がos
およびos.path
という名前で指定されていることを確認します。
>>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>
上記の例から、os
のみがローカルおよびグローバルネームスペースに追加されることがわかりました。そのため、os
を使用できるはずです。
>>> os
<module 'os' from
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> os.path
<module 'posixpath' from
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>
…path
ではなく:
>>> path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>
locals()
名前空間からos
を削除すると、それらがos.path
に存在していても、os
またはsys.modules
にアクセスすることはできなくなります。
>>> del locals()['os']
>>> os
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>
それではfrom
を見てみましょう。
from
>>> import sys
>>> from os import path
os
およびsys.modules
という名前のos.path
を確認します。
>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
そのためsys.modules
は、import name
を使用してインポートしたときと同じように見えます。
はい。 locals()
およびglobals()
名前空間の表示がどのようになっているのかを確認しましょう。
>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>
path
を使用してアクセスできますが、os.path
によるアクセスはできません。
>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>
Locals()から 'path'を削除しましょう。
>>> del locals()['path']
>>> path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>
エイリアシングを使用した最後の例:
>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>
パスは定義されていません。
>>> globals()['path']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>
from
を使用する際の落とし穴2つの異なるモジュールから同じname
をインポートすると、
>>> import sys
>>> from os import stat
>>> locals()['stat']
<built-in function stat>
>>>
>>> stat
<built-in function stat>
再度shutil
からstatをインポートします。
>>>
>>> from shutil import stat
>>> locals()['stat']
<module 'stat' from
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/stat.pyc'>
>>> stat
<module 'stat' from
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/stat.pyc'>
>>>
最後のインポートが勝つ
機能的にはほとんど違いはありませんが、最初の形式は優先的です。
from urllib import request, parse, error
2番目の形式では、
import urllib.request, urllib.parse, urllib.error
また、完全修飾名を使用して参照する必要がありますが、これはあまり洗練されていません。
違いがあります。場合によっては、そのうちの1つが機能し、もう一方が機能しません。例を示します。次のような構造になっているとします。
foo.py
mylib\
a.py
b.py
今、私はb.py
をa.py
にインポートしたいです。そしてa.py
をfoo
にインポートしたいです。どうやってこれをするの? a
に2つのステートメントを書きます。
import b
foo.py
に私はこう書いています:
import mylib.a
さて、これはfoo.py
を実行しようとするとImportError
を生成します。インタプリタはa.py
(import b
)のimport文について文句を言いますが、モジュールbはありません。それではどのようにこれを修正することができますか?このような状況では、a
とa
はどちらもb
に含まれるため、mylib
のimportステートメントをimport mylib.b
に変更しても機能しません。ここでの解決策(少なくとも1つの解決策)は、絶対インポートを使用することです。
from mylib import b
あなたはPython3を使用していますパッケージのurllibでした。どちらの形式でも構いません。どちらの形式のインポートも優先されません。場合によっては、複数のパッケージディレクトリが関係しているときには、以前のfrom x.y.z.a import s
を使用することができます。
Urllibパッケージのこの特定のケースでは、2番目の方法import urllib.request
とurllib.request
の使用は標準ライブラリがそれをどのように使用するかです。
Python 2.xでは少なくともimport urllib2.urlopen
はできません
from urllib2 import urlopen
をする必要があります
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib2.urlopen
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named urlopen
>>> import urllib.request
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named request
>>>
Import urllib.requestに対する私の主な不満は、たとえそれがインポートされなくてもurllib.parseを参照できることです。
>>> import urllib3.request
>>> urllib3.logging
<module 'logging' from '/usr/lib/python2.7/logging/__init__.pyc'>
また私の要求はurllib3の下にあります。 Python 2.7.4 ubuntu