コンテンツにスキップ

Python ファイル(.py)を実行する

とりあえず、さくっと実行

Python で、.py ファイルを import ではなくそのまま実行したい場合は

execfile("<python_path>")

このようにします。

# -*- coding: utf-8 -*-
print u"はろーわーるど"

このファイルを

execfile("S:/test_file.py")

このように実行すれば、

中のコードが実行されます。

この execfile は、import で実行するときと基本的なルールは同じで
1 行目の

# -_- coding: utf-8 -_-

がない場合は、

エラーになります。

文字コードの問題

Python ファイルを実行する場合に注意しなければいけないのが文字コード問題。
文字コードは、各エディタごとに設定ができるようになっています。

私が使っている VSCode の場合、右下のところに文字コードの設定が表示されています。

Python ファイルの 1 行目の coding:### 部分は、
このエンコード設定と同じになってる必要があります。
↑ のように、ファイル自体は「Shift JIS」になっているのに、
ファイルそのものが utf-8 になっている場合は、

# Error: (unicode error) 'utf8' codec can't decode byte 0x82 in position 0: invalid start byte
# Traceback (most recent call last):
#   File "<maya console>", line 1, in <module>
#   File "S:/test_file.py", line 2
#     print u"はろーわーるど"
# SyntaxError: (unicode error) 'utf8' codec can't decode byte 0x82 in position 0: invalid start byte #

このようにエラーになってしまいます。

# -*- coding: shift-jis -*-

エラーにならないようにするには、文字コードと 1 行目の設定を同じにすれば

エラーは発生しません。

文字コードエラーを発生させずに無理矢理 Python ファイルを実行する

execfile を使用せずに、1 行目の #encoding 設定を書かずに実行したい場合は、
Mel ファイルから実行するという手もあります。

global proc exec_python_file(string $py_path){
    string $cmd[];

    $fileId=fopen($py_path,"r");
    string $nextLine = `fgetline $fileId`;
    while ( size( $nextLine ) > 0 ) {
        appendStringArray $cmd {$nextLine} 1;
        $nextLine = `fgetline $fileId`;
    }

    string $exec_cmd = stringArrayToString($cmd,"\n");
    python $exec_cmd;
}

例がこちら。
mel のコマンドで python を実行したい場合は、python("cmd");コマンドを使用します。
コレを利用して、
fopen で python ファイルをテキストとして読み込み、文字を改行コードで結合し
その結合した結果を python コマンドで実行します。
この場合、1 行目の encoding 設定がない場合でも、エラーは発生しません。

ただし、この場合はファイル自体が Shift-Jis である必要があり
文字コードが UTF-8 などで作成されている物を Mel から実行しようとすると
文字化けしてしまい正しく実行されません。

Maya のデフォルトエンコードについては ↓
http://help.autodesk.com/view/MAYAUL/2016/JPN/?guid=GUID-88109151-076A-4AB1-836A-85370B32A256

execfile のおまけ

# -*- coding: utf-8 -*-
def test_hello():
    print u"はろーわーるど"

execfile で Python ファイルを実行したときは、グローバルに書かれた内容が実行されるだけで
書かれている関数は実行されない。
↑ のように書かれた関数を execfile で実行してから使用したい場合は

G={}
L={}
execfile("S:/test_file.py",G,L)
L['test_hello']()

このようにする。
execfile の 2、3 つめの引数に、空の Dict を入れると
その中に execfile 内の関数・変数が代入されます。
中で定義されている関数は Local 関数扱いなので 3 つめの引数「L」に入ります。

{'test_hello': <function test_hello at 0x0000015C7B715F98>}

Dict 型はこのようになっていて、関数名の Key に中に Function が入ってます。

HOGEHOGE = "fugafuga"

関数以外に、変数を定義してから使いたい場合も同様で

{'HOGEHOGE': 'fugafuga', 'test_hello': <function test_hello at 0x0000015C7B715F98>}

Key が変数名、その中身に代入された中身が入っています。

これを利用して動的に python ファイルをロードする事も出来ますが、
動的ロードをしたい場合は execfile を使用するよりも
importlib を使う方が良いです。

importlib については ↓
https://qiita.com/progrommer/items/abd2276f314792c359da


最終更新日: 2020-07-11 15:53:43