質問: sys.argv[1] fetch_and_save_img(word) ``` ### 知りたいこと オブジェクト指向を詳しく知るのは難しいと思うので、このプログラムにおいてなぜクラスを用いるのか、用いらずに関数のみを用いた場合どのような支障をきたすのか、教えていただきたいです。 よろしくお願いします。
回答: オブジェクト指向を使うことによって、コードを読む人の理解を助けることができます。 今のコードの場合、Fetcherというクラス名はfetchを行うためのメソッドを持つと連想されることができます。 このクラスにはもっといろいろと行うことを付け足すことができるはずです。 例えば、.update_ua(new_ua)というメソッドでどこかでアドレスを変更することなどが考えられます。 プログラミングでは同等の機能をいくつもの方法で実装できます。 素朴に関数として実装された場合と比べると、ockeghemさんが指摘されているようにuaという属性に自由度をもたせつつ、グローバル変数の空間を汚さないことが実現できます。 同じ目的でも、今回のクラスでの実装以外にクロージャ(関数を生成する関数)を用いることもできます。 以下にコードを示します。 この場合、一度与えたuaを今後変更することは自然ではなくなります。 それと引き換えに、fetcher.fetch(url)の代わりにfetch(url)とコードが少しスッキリします。 実装の方法が数多ある中で、適切な実装をすることでコードは読みやすくなり、バグりにくくなります。 プログラミングする際には入力に対して正しい出力を出すことだけが重要というわけではありません。 同じコードが他のところで再利用されたり、長い間変化しながら使用され続ける可能性をも考えることで、オブジェクト指向を用いることの必要性について評価することができるかと思います。 ``` def generate_fetch(ua): def fetch(url): req = Request(url, headers={'User-Agent': ua}) try: with urlopen(req, timeout=3) as p: b_content = p.read() mime = p.getheader('Content-Type') except: sys.stderr.write('Error in fetching {}\n'.format(url)) sys.stderr.write(traceback.format_exc()) return None, None return b_content, mime return fetch fetch = generate_fetch('任意のメールアドレス') byte_content, _ = fetch(url) ```