【python】適当に名前を付けると、ビルトイン関数を上書いたり、衝突したりする
python
を勉強初めの時は、python
が用意してくれてる関数を書き換えることができるっていう概念がなかったので、あれ?ってなるやつ
ビルトイン関数と同じ名前の変数を定義しちゃう
import json print(json) json = json.dumps({'hogehoge': 'foo'}) print(type(json))
上書きできるって概念がなくても同じ名前があると混乱するし読みづらいので、なかなかこんな書き方はしないと思うけど。。。一応
[実行結果]
<module 'json' from 'C:\\InstallDir\\Python\\Python37\\lib\\json\\__init__.py'> <class 'str'>
json.dumps
の結果(文字列型)でjsonを上書いてしまっているので、後続でjson
モジュールの関数予防とするとobject has no attribute
のエラーが出てしまう
ビルトイン関数の同じファイル名を作っちゃう
python
の勉強始めたばかりだと・・・
「今日は、json
モジュールの使い方を勉強しよっと」
「json
ってファイルを試しに作ってテストするよ!」
こんな感じで、実行させようとするけど↓のようなエラーが出る
import json json_str = json.dumps({'hogehoge': 'foo'}) print(json_str)
[エラー内容]
json_str = json.dumps({'hogehoge': 'foo'}) AttributeError: module 'json' has no attribute 'dumps'
初学者だと、本と見比べて「一字一句間違いないのに、なんでエラーが出るんだ!?」ってなるやつ これは、学習しはじめの時だとファイル名にまで意識が言ってないので気づけないことも多い気がする(自分だけかな?)
パッケージ名でも衝突する(予想外のところで)
スクレイピングするバッチを作成していて、requestsをラップしたパッケージを作ろうとして・・・
http
っていうパッケージ名をつけて、その下にclient.py
ファイル内で、import requests
したらエラーがでた
こんな感じでパッケージをつけてた
[エラー内容]
Traceback (most recent call last): File "D:/Develop/euibatch/http/client.py", line 1, in <module> import requests File "D:\Develop\euibatch\venv\lib\site-packages\requests\__init__.py", line 43, in <module> import urllib3 File "D:\Develop\euibatch\venv\lib\site-packages\urllib3\__init__.py", line 7, in <module> from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url File "D:\Develop\euibatch\venv\lib\site-packages\urllib3\connectionpool.py", line 11, in <module> from .exceptions import ( File "D:\Develop\euibatch\venv\lib\site-packages\urllib3\exceptions.py", line 2, in <module> from .packages.six.moves.http_client import IncompleteRead as httplib_IncompleteRead ImportError: cannot import name 'IncompleteRead' from 'http.client' (D:\Develop\euibatch\http\client.py)
ようするに、requests
モジュール内で使ってるものとhttp
のモジュールが衝突したみたい
解決するにパッケージ名を衝突しない名前に変えるか、衝突しないようなトップレベルのパッケージを一つ作成してその中に配置するかって感じかな
まとめ
python
的には java
のパッケージ作成でよくみるsrc/co/jp/<プロジェクト名>
みたいなつけ方するのってどうなんだろう?
っと思ったけど、
のような記事があった。javaのように1ファイル1クラスみたいな扱いじゃないから、
- 関連処理であるなら、多数のクラスを1ファイルにまとめる
- それでも規模がでかくなってきたらパッケージで分割を考える
- pythonファイルは、それ自体が
java
のパッケージみたいなもの - pythonパッケージは、それをさらにまとめた大きなパッケージみたいなもの
割と大雑把な理解だろうけど、こんな認識でいいのかな。