質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4492閲覧

pythonの自作関数内でexec関数は動作するのか?

csko17118

総合スコア1

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/04/30 08:16

編集2020/04/30 13:18

前提・実現したいこと

自作関数の中でソースコードとなるテキストを生成し、それを同じexec関数の中で読み込みたい

ここに質問の内容を詳しく書いてください。
なぜこのようなことをしてたいかとというとsympyでn次元勾配ベクトルとn行n列のヘッセ行列の計算を自作関数でモジュール化したいのですが、そのためのsympy内での変数の定義がうまくいかないことです。そこで上記のように対策したのだがうまくいかなくて困っている。

該当のソースコード

なぜこのようなことをしてたいかとというとsympyでn次元勾配ベクトルとn行n列のヘッセ行列の計算を自作関数でモジュール化したいのですが、そのためのsympy内での変数の定義がうまくいかないことです。例えば2次元ベクトルで定義する場合,x=[Symbol('x[0]'),Symbol('x[1]')]のように描かなければならないのですが、これをn次元でやろうとするとx=[Symbol('x[0]'),Symbol('x[1]')・・・,Symbol('x[n-1]')]となってしまうためソースコードがかけません。そこで以下のような自作関数をまず定義しました。

def defx(n): name1='Symbol(' #変数xベクトルの定義(開始) name2="'" name3='x[' name4=']' name5='),' name6='x=[' u='' for i1 in range(n): u=u+name1+name2+name3+str(i1)+name4+name2+name5 u=u[:-1] vx=name6+u+name4 return vx

そして、このファイルをsympy_Multivariable.pyと名付け、anacondaのsite-packages内に自分で作った
myfunction\math\define内に保存しました。

こうすることで
jupyter notebookで

from myfunction.math.define import sympy_Multivariable as SMV defx=SMV.defx(6) print(defx)

と入力すれば

x=[Symbol('x[0]'),Symbol('x[1]'),Symbol('x[2]'),Symbol('x[3]'),Symbol('x[4]'),Symbol('x[5]')]

と表示されます。

ここからが本題です。
まずこのように自作関数をつくりました。

from sympy import * from sympy import sin,cos,tan,exp,log from myfunction.math.define import sympy_Multivariable as SMV      #上のテキストを生成するための自作関数 def grad(L,n):                                #n次元勾配ベクトルを生成するための自作関数 defx=SMV.defx(n)                            #xの定義コードを自作関数からテキストとして生成      exec(defx) #変数xの定義 nL=[diff(L,x[i1]) for i1 in range(n)] return nL def Hesse(L,n): #ヘッセ行列を生成するための自作関数の定義 defx=SMV.defx(n)                             #xの定義コードを自作関数からテキストとして生成  exec(defx)                                #変数xの定義 nL=[diff(L,x[i1]) for i1 in range(n)] HL=[[diff(nL[i2],x[i3]) for i2 in range(n)] for i3 in range(n)] return HL

ちなみにこの自作関数のファイルはdiff.pyと名付け、anacondaのsite-packages内に自分で作ったmyfunction\math\analysis内に保存しました。

そして今度はjupyter notebookで以下のようなソースコードを組んでみました。

from sympy import * from sympy import sin,cos,tan,exp,log from myfunction.math.analysis import diff #勾配ベクトルとヘッセ行列の自作関数 from myfunction.math.define import sympy_Multivariable as SMV   #変数xの定義コード生成のための自作関数 n=2 #変数の数nの決定 defx=SMV.defx(n) #xの定義コードを自作関数からテキストとして生成  exec(defx) #変数xの定義 f=sin(x[0]*x[1]) #勾配ベクトルとヘッセ行列を求めるための関数f nf=diff.grad(f,n) #勾配ベクトルの計算 Hf=diff.Hesse(f,n) #ヘッセ行列の計算 print(nf) #勾配ベクトルの表示 print(Hf) #ヘッセ行列の表示

このプログラムを実行したときに勾配ベクトルとヘッセ行列の自作関数が定義されていないとエラーメッセージが出るのですがそもそも、自作関数内でexec関数が動作しないということなのでしょうか?

この原因についてわかる方がいたら教えてください。
■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

NameError Traceback (most recent call last) <ipython-input-6-cf230244345a> in <module> 9 exec(defx) 10 f=sin(x[0]*x[1]) ---> 11 nf=diff.grad(f,n) 12 Hf=diff.Hesse(f,n) 13 print(nf) ~\Anaconda3\lib\site-packages\myfunction\math\analysis\diff.py in grad(L, n) 6 defx=SMV.defx(n) 7 exec(defx) ----> 8 nL=[diff(L,x[i5]) for i5 in range(n)] 9 return nL 10 ~\Anaconda3\lib\site-packages\myfunction\math\analysis\diff.py in <listcomp>(.0) 6 defx=SMV.defx(n) 7 exec(defx) ----> 8 nL=[diff(L,x[i5]) for i5 in range(n)] 9 return nL 10 NameError: name 'x' is not defined

試したこと

exec関数を用いて、n次元ベクトルの定義を試みた

補足情報(FW/ツールのバージョンなど)

jupyter notebook ,atom ,hydrogen

###感謝
テキストの編集を教えてくれた方ありがとうございます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2020/04/30 10:46

インデントが潰れたりしてコードが読めないので編集して修正してください。 ``` ここにコードを書く ``` のように囲うと綺麗に表示されます。
csko17118

2020/04/30 13:07

めちゃくちゃ参考になりました、ありがとうございます。 ```にそのような意味があったとは、驚きです。 本当にありがとうございました。
guest

回答1

0

ベストアンサー

スコープの関係でexecによる代入はほとんど意図通りに動作しません。私の書いた記事ですが、

【python】execを使って変数名を動的に変える方法についての考察 - 静かなる名辞

を読んでください。


これをn次元でやろうとするとx=[Symbol('x[0]'),Symbol('x[1]')・・・,Symbol('x[n-1]')]となってしまうためソースコードがかけません

こちらを書いた方が楽だと思いますが……

python

1# Python3.6以降を想定。3.5以前ではstr.formatメソッドを使ってください 2x = [Symbol(f"x[{i}]") for i in range(n)]

投稿2020/04/30 19:56

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

csko17118

2020/05/01 13:52

返信ありがとうございます、上のコードで動かすことができました、またexec関数にはそのような性質があったのですね、とても参考になりました、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問