ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

スマートPythonプログラミングその2

はじめに

引き続きスマートPythonプログラミングをやっていきます。

take-she12.hatenablog.com

落とし穴を避ける

Pythonの落とし穴を避ける方法についての章です。

Pylint

文法の静的チェックとしてpylintをオススメしています。pipでいれてみましょう。

[vagrant@smartpython ~]$ sudo pip install pylint
You are using pip version 7.1.0, however version 8.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Collecting pylint
/usr/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
  Downloading pylint-1.6.4-py2.py3-none-any.whl (569kB)
    100% |████████████████████████████████| 569kB 494kB/s
Collecting six (from pylint)
  Downloading six-1.10.0-py2.py3-none-any.whl
Collecting backports.functools-lru-cache (from pylint)
  Downloading backports.functools_lru_cache-1.3-py2.py3-none-any.whl
Collecting configparser (from pylint)
  Downloading configparser-3.5.0.tar.gz
Collecting isort>=4.2.5 (from pylint)
  Downloading isort-4.2.5-py2.py3-none-any.whl (40kB)
    100% |████████████████████████████████| 40kB 631kB/s
Collecting mccabe (from pylint)
  Downloading mccabe-0.5.2-py2.py3-none-any.whl
Collecting astroid<1.5.0,>=1.4.5 (from pylint)
  Downloading astroid-1.4.8-py2.py3-none-any.whl (213kB)
    100% |████████████████████████████████| 217kB 807kB/s
Collecting lazy-object-proxy (from astroid<1.5.0,>=1.4.5->pylint)
  Downloading lazy-object-proxy-1.2.2.tar.gz
Collecting wrapt (from astroid<1.5.0,>=1.4.5->pylint)
  Downloading wrapt-1.10.8.tar.gz
Installing collected packages: six, backports.functools-lru-cache, configparser, isort, mccabe, lazy-object-proxy, wrapt, astroid, pylint
  Running setup.py install for configparser
  Running setup.py install for lazy-object-proxy
  Running setup.py install for wrapt
Successfully installed astroid-1.4.8 backports.functools-lru-cache-1.3 configparser-3.5.0 isort-4.2.5 lazy-object-proxy-1.2.2 mccabe-0.5.2 pylint-1.6.4 six-1.10.0 wrapt-1.10.8

以下のコードがテスト対象です、

[vagrant@smartpython ~]$ cat test.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

def main():

    foo = 'Hello, world!'
    print(foo)

    unused = 1

    return

    print(foo)

if __name__ == '__main__':
    main()

めっちゃ分析してくれますね。

[vagrant@smartpython ~]$ pylint test.py
No config file found, using default configuration
************* Module test
C:  7, 0: Unnecessary parens after u'print' keyword (superfluous-parens)
C: 13, 0: Unnecessary parens after u'print' keyword (superfluous-parens)
C: 18, 0: Trailing newlines (trailing-newlines)
C:  1, 0: Missing module docstring (missing-docstring)
C:  4, 0: Missing function docstring (missing-docstring)
C:  6, 4: Black listed name "foo" (blacklisted-name)
W: 13, 4: Unreachable code (unreachable)
W:  9, 4: Unused variable 'unused' (unused-variable)


Report
======
8 statements analysed.

Statistics by type
------------------

+---------+-------+-----------+-----------+------------+---------+
|type     |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module   |1      |NC         |NC         |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|class    |0      |NC         |NC         |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|method   |0      |NC         |NC         |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|function |1      |NC         |NC         |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+



Raw metrics
-----------

+----------+-------+------+---------+-----------+
|type      |number |%     |previous |difference |
+==========+=======+======+=========+===========+
|code      |9      |47.37 |NC       |NC         |
+----------+-------+------+---------+-----------+
|docstring |0      |0.00  |NC       |NC         |
+----------+-------+------+---------+-----------+
|comment   |2      |10.53 |NC       |NC         |
+----------+-------+------+---------+-----------+
|empty     |8      |42.11 |NC       |NC         |
+----------+-------+------+---------+-----------+



Duplication
-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |NC       |NC         |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |NC       |NC         |
+-------------------------+------+---------+-----------+



Messages by category
--------------------

+-----------+-------+---------+-----------+
|type       |number |previous |difference |
+===========+=======+=========+===========+
|convention |6      |NC       |NC         |
+-----------+-------+---------+-----------+
|refactor   |0      |NC       |NC         |
+-----------+-------+---------+-----------+
|warning    |2      |NC       |NC         |
+-----------+-------+---------+-----------+
|error      |0      |NC       |NC         |
+-----------+-------+---------+-----------+



Messages
--------

+-------------------+------------+
|message id         |occurrences |
+===================+============+
|superfluous-parens |2           |
+-------------------+------------+
|missing-docstring  |2           |
+-------------------+------------+
|unused-variable    |1           |
+-------------------+------------+
|unreachable        |1           |
+-------------------+------------+
|trailing-newlines  |1           |
+-------------------+------------+
|blacklisted-name   |1           |
+-------------------+------------+



Global evaluation
-----------------
Your code has been rated at 0.00/10

ほとんどがコーディングスタイル違反を意味するCのようです。

しかし細かく分析してくれるのはうれしいですね。今思えばrubyで静的解析使ったことないなぁ。

条件分岐と真偽値

どの言語でも何がTrueかFalseかは注目されますね。boolメソッドを使えば真偽値が分かるということですね。空文字や空配列がfalseになるようです。

非推奨のモジュール

importすれば使えるpython標準モジュールのことでしょうか。rubyでいうところのSetとかそのあたりかな。Deprecatedになってないか注意して使いましょうということですね。

紹介されていますが、そもそもの知識がないのでskip。

Pythonらしく書く

ここから急に難しくなりますね。Python初心者にはつらいところ。

イテレータとコンテナ

イテレータrubyにもあるのでわかりますよ。

[vagrant@smartpython ~]$ cat iter.py
iter = [1,2,3]
for i in iter:
    print(i)

実行するとこうなる。

[vagrant@smartpython ~]$ python iter.py
1
2
3

辞書、リスト、集合などをイテラブルなオブジェクトと呼びます。

なるほど、これらのイテラブルなオブジェクトの内部でイテレータオブジェクトは使われていて、このイテレータはnextで次に渡されたら中の要素は消えてしまうということですね。

そしてその間に存在するのがコンテナオブジェクト。イテラブルなオブジェクトは中身を一度コンテナオブジェクトに渡して、そこからイテレータオブジェクトを生成するといったイメージでしょうか。

内包表記

例えばリストでいえば、[]の中身にリストの要素を返却するロジックを記述すれば行数を少なくできる、という感じでしょうか。

確かにこれは楽ですね。横着している気分。

デコレータ

これ、仕事中に出てきてわからなかったやつですね。Pythonできる同期に聞いたんでした。

関数をデコレートして、付加価値をつける仕組みですね。例えばこの関数を呼び出す前にかならず行いたい処理を足したりできます。

これは面白い仕組みだと思います。コードを読む立場は大変だと思いますが、いろいろなことができる可能性がある。Pythonらしさのために必要なんだろうなと思いますね。

コンテキストマネージャ

ある処理の前後に何かをするときに使われるという。

with句のことをコンテキストマネージャと言うんですね。

おわりに

ちょっとPythonを一通り触っているひとでないと理解が難しい領域になってきました。想定読者は入門書終わったひとって言ってるんですから当たり前ですけれども。今回一周しておいて、また戻ってこれるような本だと思います!

次回で残り2章をやって終えたいと思います!