Pepper のアプリで Python のライブラリや独自モジュールがうまくインポートされない時の対処法


はじめに

Pepperのアプリ開発にあたって、よく使われているライブラリや、独自のPythonモジュールをインポートする際、意図した通りにインポートされないという事象に出くわしたので、対処方法をこちらに記載します。
同じ問題に直面した際の一助として頂ければ幸いです。

前提条件

以下の環境で試しています。

  • MacBook Pro Retina 2015 13inch
  • Choregraphe 2.5.5.5

問題1) モジュールの修正が適応されない

独自にモジュールを実装して利用する場合、当然ですがそのモジュールを修正する必要が頻繁に生じます。
モジュールを修正して import すれば良いはずですが、うまくいきません。
実際にどういうことが起こるのか、サンプルを用いて以下に記載していきます。

サンプルの概要

サンプルとして使用する Python モジュールは、文字列を引数で受け取ったら、Choregrapheのログに出力するだけの簡単な機能で実装しています。

① 独自モジュールが入っているディレクトリ
② 「AddLibPath」ボックスでライブラリのパスを指定しています。
* ライブラリパス指定は、pepperに外部モジュール追加してみる。とりあえずrequestsで。を参考してください。
③ 「Print Text」ボックスでは、文字列を受け取り、モジュールの関数を呼んでいます。
④ 正常にログに出力されています。

まずは独自モジュールを作ってボックスでインポート

簡単な独自モジュールを作ってみます。

custom_modules.py
# -*- coding: utf-8 -*-

'''
app_name.custom_modules
独自モジュール
'''

# 引数をログに出力
def print_text(box_self, _text):
    '''
    ・引数
        _text : 出力する文字列
    ・結果
        _textをログに出力する    
    '''

    temp_text = "print: " + _text

    box_self.logger.info(temp_text)

次に、作ったモジュールをボックスでインポートして使ってみます。

def onInput_onStart(self, input):
    from app_name import custom_modules

    custom_modules.print_text(self, input)

正常にログに出力されますね。


モジュールを少し修正し、再実行してみましょう

custom_modules.py
#temp_text = "print: " + _text
temp_text = "プリント: " + _text

あれ、変わってない…

本サンプルでは同一の関数内で出力を変えているだけですが、
例えば修正後のモジュールで新しい関数を追加して呼び出すと、エラーが発生してしまいます。

解決方法

モジュール実行前に明示的にリロードしましょう。
アプリ起動後の初期化処理時などに組みこむといいかと思います。

import app_name
reload(app_name)
import app_name.custom_modules
reload(app_name.custom_modules)

そのあと、実行してみると

意図通り修正内容が適応されてることが確認できます。

問題2) 意図しないライブラリをインポートしてしまう

例えば、Pepper 内にすでにインストールしてあるライブラリの異なるバージョンをlibの直下に置いてインポートすると、自分がプロジェクトに入れたバージョンを参照せず、Pepper 内のバージョンを参照することがあります。
(正確には importする際の sys.path 値の順序に依存します)

下記の例を見てみましょう。

libの直下にv2.6.0requestsモジュールを置きます。

その後、インポートし、

import requests 

v2.4.2requestsで追加された引数であるjson_にパラメータを指定してPOSTをしてみると

url = 'https://api.github.com/some/endpoint'
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post(url, json=payload)

エラーが発生してしまいました。

参照しているrequestsのバージョンを見てみると、v2.6.0ではなく、v2.3.0になっています。
v2.3.0 は NAOqi OS 2.5.5 に元々インストールしてある requests のバージョンです。
従って、v2.3.0 よりあとのバージョンで追加された機能は使用できないのです。

解決方法

libの直下に、自身のアプリのIDなどのディレクトリを作り、__init__.py ファイルと入れたいライブラリを入れます。
独自の名前空間を持ったパッケージを作る感じですね。

その後、正しいパスを指定しインポートして、再度、実行してみると

from app_name import requests 

意図通りv2.6.0のrequestsモジュールが参照され、機能も無事使えるようになります。

まとめ

  1. 独自モジュールの変更内容が適応されない時は、明示的にリロード
  2. 独自のパッケージ名で名前空間を分けてから import を行う