水深1mm

広く浅い個人的メモ。

DaikinのPythonセミナー:ざっくりメモ

2016/11/10にあったDaikinのPythonセミナー行ってきた。

時間がなく、自動化とテストについてはほぼ話が聞けなかったので残念。

ツール開発の仕組み・ルールがきちんと組み立てられていてとても参考になった。
UI層・ライブラリ層・アプリケーション層というのは、一応自分の中で切り分けて考えて
実装を行っていたつもりだったが、パッケージを分けるまではやっていなかったので
そのあたり意識して作業しようと思った。

後日セミナーに使用した資料がダウンロードできるようになるらしいので確認する。

以下、セミナー内容のメモ。
聞いている最中に書いたので誤字脱字・聞き洩らし・解釈違い多々あり。

Pythonセミナー

スマイルテクノロジーユナイテッド株式会社
代表 高橋涼氏

新人向けの資料をもとに作成した

社内の開発ツールが多かった

たくさんあるとノウハウ共有の障壁

  • 1つに絞りたい
    • かといってC++は低レベルすぎる

CGはほぼPython対応している

  • WebもやっているがそれもPythonでOK

基本的な開発ルール

  • 目的

  • チームの成果物はチームで全員保守

  • 他人の書いたコードの内容を把握する時間短縮
    • コードレビューの品質向上
    • チームの責任においてメンテの義務がある
  • 予測できるバグの防止
  • ルールは相互に補い合う

  • 2回嫁

  • ソースのTemplate

    • ルールでパターンがある
    • そのルールをTemplateで共有する
      • Templateはプラットフォームそれぞれにある
  • ルール化した理由は文書化してWikiで共有

VCSによる管理

  • ブランチを切る

    • master
    • develop
  • VCSでの配布のメリット

    • NAS共有の問題
      • 不具合が発生すると全員に影響
    • ファイルの配布の問題
      • 上書きだと削除する必要のあるファイルまで面倒見切れない
    • 独自インストーラ

      • その労力を開発に使いたい
    • メリット

      • 不具合の場合に使用者側で前のバージョンに戻せる
      • 更新しないという選択もできるようになる
    • .pycの削除は別途行っている

よく使うサードパーティ製ツール

  • jinja2
    • テンプレートシステム
    • Djangoのテンプレートシステムを参考に単独で実装
  • lxml
  • pillow
    • 画像処理
  • requests
    • httpクライアント
  • simplejson

    • BOM関係で?
  • 推奨モジュールの策定

    • 多数の選択肢によるブレをおさえる
    • エクセル読み込むという処理も選択肢がいっぱいある
      • それをルール化
      • xlrdを使っている
    • 同時にAliasの名前も統一する
  • pip

    • パッケージマネージャ
    • wheelフォーマットの策定によりバイナリ配布も可能になった
  • パッケージの用意

    • Pypiにない場合
    • Unofficial windows Binarisからダウンロード
    • それでもない場合はソースから
  • virtualenv

    • 新たに導入するサードパーティ製のものについては一度Virtualenvで確認する
    • requirments.txtに追加して配布
    • それを使ってpipでインストールという流れ

    • Scripts/activate.batでcmdでvirtualenvの環境を実行できる

  • Mayaでもpipで管理出来る

    • 注意
      • Maya用にwheelを別途用意する必要がある
      • manifest情報が無いためそのままでは読み込めない
      • githubでツールを公開している

PEP8準拠のコードスタイル

コミュニティで共有されているスタイル - Githubで共有されているコードはほぼすべて準拠している

  • コレは守らないとやばい
  • import *

    • 定義されている場所が不明
    • Aliasを指定することで短縮化出来る
  • 1行は99文字まで

    • 現在は画面が広くなったので79文字ではなく99文字でも可
  • 4スペースインデント

    • タブはエディタでスペース数が変わる(環境によって意味合いが変わる)
  • ファイルエンコーディング

    • UTF-8(BOM付)
    • VSがこれ対応だから
    • 実は問題あるが解決可能
  • 文字列は徹底してUnicode

  • python3を見据えたルール

    • MayaがPython3になる日を見据え互換性を意識する
  • python2で3と同様の機能を使用する

    • future 使え!!
    • printが文から関数に変更
    • int同士の割り算の結果がintからfloatに変更
    • 相対パスimportが廃止された

      • 3はフルパスでの記述必須
    • 文字列フォーマティング

      • × '%s %s' % ('dog', 'cat')
      • ○ '{0} {1}'.format('dog', 'cat')

      • 長い文字列を埋め込むとか複雑なものについてはTemplateエンジンを使用する -外部ファイルに書き出してから使用する?

  • チェッカーを利用する

  • 目視では不可能

    • pep8.py
      • 現在は名前が変わった
      • 基本的なPep8をチェックを行っているコマンドツール
    • 一度autopep8にかけるといいかも(弊社ではやってない)
  • 静的解析

    • pyflakes
      • 定義されていないものとかをチェックしてくれる
      • 例外などの定義されていないものもチェックしてくれる

flake8でのチェック

  • flake8でのチェック(これ使ってる)

    • pep8基本的なチェックのみ

      • プラグインとしていろんなチェックを追加できる
      • サードパーティ製のチェッカーを利用する

      • いくつかのチェッカーを統合したflake8を採用

      • 除外する警告についてはtox.iniに記述するとイイよ

    • Hacking(OpenStackのガイドライン)というキツめにチェックしてくれるヤツ

  • コードレビュー

    • 特別なツールは使ってない

      • リーダーチェックのみ
      • Slackで連絡
      • ホワイトボードで議論
      • 小規模ならこれでOK
    • Githubのコードレビューは優秀(PullRequest)

    • サードパーティ製のツールにプルリク
  • Templateのルール

    • 初めに呼ばれる関数は「main」

    • 終了コード(成功時)は0、失敗は0以外

      • 例外が発生した場合には0以外を返す
    • 引数の初期化・ロガーの初期化もルール化

エディタを選ぶ

  • 新人だとメモ帳で書いたりする人もいる?

  • 生産性にダイレクトに影響するので妥協せずにこだわるべき

  • PyCharmを使用している

    • リモートデバッグは有料のProfessionalのみ
    • 個人向けライセンスを業務に使用しても良い
      • でもそれに対して会社が金を出すのはダメ
  • 無料でリモートデバッグ

    • VSとかでOK
  • エディタで求められる機能

  • 実行環境

  • あると好ましい機能

    • いろいろ

Pythonで作ってみよう

  • Mayaの開発環境

    • 言語は英語
  • Maya.envでパスを通す

  • 作業ブランチと開発ブランチを別にenv作成

  • UserSetup.melでLoggerの初期化など

  • 作ったものを説明

    • 決められたオプションでバインド
    • 骨のWeightの転送
    • Weightのコピー
  • ユースケース

  • 全てPyMELで実装

    • maya.cmdsを禁止
  • PyMELとは

    • 文字列ではなく適切に解析されたオブジェクトを返す
    • 一部APIもOK
    • メンテナンスすべきコードが減らせる

    • 禁止

      • オペレータによるAttrのコネクト禁止
      • Undo不可能なAPIは使用禁止
      • GUIはPySideで実装
  • 実行関数から実装する

    • パラメータは引数で受け取る
    • GUIに依存したものはMayabatchで実行できない
  • MELコマンドで実装された資産を生かすのがMayaのメリット

    • あくまで機能の確認
    • 著作権は確認しよう
  • MELコマンド=Python関数の調べ方

    • 以下の説明に含む
  • その1

    • Maya基本機能を把握
      • ドキュメントを読む

        • ユーザガイド
        • テクニカルドキュメント
          • MEL・PyMel
      • 1月に1度読む!!

  • その2

    • 選択するコマンドは❓

    • 実行してみてコマンドを確認

      • whatIsで調べる
        • CommandではなくProcの場合はファイルのパスが出る
      • それをPyMELで呼び出す
  • その3

    • バインドするコマンドは?
    • スクリプトエディタに出ない・・・

      • コマンドを全表示にする
    • ProgramFilesのMELスクリプトを読む

      • バインドはskinClastorCallback.mel
      • whatIsを駆使してめっちゃ辿る
    • 内部のコマンドを使用するときはpm.mel.~で呼べる?

  • モジュール管理

    • ネームスペース=パッケージ・モジュール
      • パッケージ:ディレクト
      • モジュール:ファイル
      • 総称してモジュールと呼ぶことが多い
    • 会社名など重複しないパッケージ名にする
      • 大文字禁止
    • 2つに分けて考える

      • アプリケーション層
        • app/init.py
      • ライブラリ層
        • stu/init.py
    • 全体構造の概要

      • パワポの画像参照
      • UI層はユーザーが実際に触る部分(GUICUI)
    • 読みやすいコード

      • 深いネストは避ける!!
    • 関数名

      • 関数名は「動詞_対象」
      • 真偽はis
      • 変更する関数(破壊的処理)は「set」「modify」を付ける
    • 無意識の破壊的処理

      • 一見変更されていないように見えてもログで確認
    • クラス名

      • Managerというのはダメ
        • 何も考えてないのと同じ
      • ~erとかも悪い例
    • サンプルのコメントの書いてあるところごとに関数化すべきかもね

  • ウェイトのコピーを実装

    • 頂点番号の対応する頂点にコピー

    • Pythonらしい書き方

      • ファイルライクオブジェクト

        • read/write メソッドを持つ
        • 代表はFile
        • ファイルを扱うように実装できる
          • メモリ内で完結できる
        • cStringIOを使用して実装できる?
      • read・write時に実際にファイルか・メモリ上にあるかどうか気にしなくていい

    • コンテナのおさらい

      • いろいろ
    • OrderdDictはJsonに書き出すときは順番を保持しない

      • 順番が重要な場合はListを使用する
  • コマンドライン

    • バッチはコマンドで行う(メモリ効率がイイ)

    • mayabatchではなくmayapyを使用

    • 例外に対してはTemplateで対応?

    • バッチ処理は必ずプロセスごとに並列化

      • プロセスセーフであることが期待される
  • ロガーの正しい使い方

    • 役割
      • エラー原因
      • ユーザーに対するレスポンス
    • プリントでログ表示はやめよう

      • 開発中のログとユーザのログは一致しない
      • 時刻などの付加情報を自分で管理は無駄
    • loggerモジュールを使用する

      • 出力レベルを設定できる

      • 階層管理ができる

        • ドットで階層管理可能
        • ロガーはプロセスで共有される
          • Rootロガー(logging.info()で呼ばれる)は使用禁止
          • Mayaは起動時に初期化
      • 出力レベルを指定

        • logger.setLevel(LOG_LEVEL)
        • 指定したレベルのログが出力

          • envで切り替え
        • ハンドラーで出力先を指定

          • 標準
          • ファイル
          • メール
  • PyCharmでデバッガーを使用する

    • ログの追跡で原因がわからない
      • 情報が多すぎるのでデバッガーを使用する

      • Mayaとリモートデバッグで接続するとPyCharmのConsoleでPyMELコマンドのHintingが出来る

  • 混乱しない例外処理

    • ストレージ・ネットワークが整っていないなどで処理を停止する目的で使用する

    • 処理の分岐のために例外を発生させない

      • 最低限 安全確保のためにファイルCloseしてraise
    • Exceptionを指定しないのは言語道断
      • キーボードの例外すら握りつぶす
    • 予測できる例外は自分で専用の例外を作成する
      • Exceptionを継承
  • PySide

    • Mayaにも入っているが別途インストールする

      • pyside-uicがないため
    • QtDesignerでuiファイルを作成

    • Widgetをベース
    • こだわり始めるときりがないので

      • グループやタブのネストは禁止(最大3まで?)
      • Templateとなるものを用意する
    • 必ずHELP・SetDefault・Executeを用意

    • List/Tableは~Widget使用禁止

      • ~Viewを使用する
  • Pythonスクリプトへの組み込み

    • Designerでのシグナル設定は禁止

      • 限界があるのでロジックはすべてPythonに集約
    • uiファイルをPythonに変換してから使用する

      • iconを使用するとリソースファイルができるのでそれは「pyside-rcc」(?)で変換する
    • uiファイルから変換したpythonモジュールをimportしてQWidgetと多重継承

    • シグナルについてはドキュメントを見て確認してからコードを実装

  • コールバックと実行関数の分離

    • コールバック内ですべての処理を書くとGUI依存となりバッチ処理が行えない
    • 内部処理を別にしてコールバックは最低限にする
  • デコレータ

    • 関数を受け取って関数を返すヤツ
  • ユーザーにはMELコマンドとして配布する

  • doctestについて

    • テストコードは書いてね

    • 機能追加・不具合修正の確認

    • めんどい

    • 仕様書がないから毎回手順が違う

    • Libの場合変更があるとすべてに影響が出る

      • から書こうぜ!!
    • doctest

      • ライブラリの関数テストに最適
      • docstringにインタプリタの記述を書く
    • 1コードでMayaの全バージョンをサポートする

      • メリット

        • バージョンの選択が自由
      • 修正は全てのバージョンが影響を受ける

      • テストにはmayapyを使用する
  • 自動化

    • doctesnot自動化
      • unittest/flake8が登録済み
  • まとめ

    • 学習リソース
      • ドキュメントを読む
      • ソースを読む
      • トレンドを知る