asahi4549
@asahi4549 (asahi kit)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【python】別ファイルの変数を参照したいときのやり方

Discussion

Closed

pythonにおいて別ファイルの変数を参照したいときにどう考えたらよいのか意見もらえたらと思います。

例えば以下のようなコードの時です。以下コードはclass_test.pyの変数xに応じて
class_func.pyの関数calc_timesの処理内容を分けるコードになっています。
※関数の引数を2つに増やすことはできない

class_test.py
import func_test as fc

x = 2
class master:
    def __init__(self):

        a = 1
        b = fc.calc_times(a)
        print("b={} ".format(b))


if __name__ == '__main__':
    ins_mas = master()
func_test.py
import class_test as cl

def calc_times(args):
    if(cl.x != 0):
        return args * 2
    else:
        return 0

私は、上記コードのように
"使いたい変数が定義してあるファイルをimportする"
方法を使います。
しかし、これではその変数が書き換えられるリスクが高いのではと思っています。
これ以外の方法があれば意見もらいたいです。お手数をおかけしますがよろしくお願いいたします。

0

例のコードからは変数を共有して何がしたいのか読み取れないので答えづらいですね。変数の役割によると思います。

1. 定数を定義する場合

プログラム全体で使う値を1箇所で定義して他のファイルから参照するとき、実行中に書き換えられることがないと分かっている、または書き換えて欲しくない変数の名前は大文字にして定数だと分かるようにします。

Python 言語には定数の概念はないので、変数名を大文字にしても何の効果もありません。しかしプログラマの間での約束事としては定数は書き換えないことになっています。これで変数が書き換えられるリスクを抑えられます。

mymath.py
PI = 3.14
main.py
from mymath import PI

print(f"My PI is {PI}")

2. 書き換えられることがある変数を定義する場合

書き換えられることがある変数を他のファイルから参照するときは、書き換えについてのルールを決めてコメントに明記します。

myconfig.py
# プログラムの設定を格納するグローバル変数
#
# - プログラムの先頭で一度だけ init_global_config() を呼ぶこと
# - メインの処理が始まったら書き換えないこと
global_config = {}

def init_global_config():
    global_config['enable_logging'] = False
main.py
import sys
from myconfig import global_config, init_global_config

init_global_config()

if sys.argv[1] == '--log':
    global_config['enable_logging'] = True

# メインの処理開始
...
0Like

しかし、例のコードを見るに、本当にやりたいことは「関数の引数の数は変えないで、関数の挙動を外から変えられるようにする」ではないでしょうか? それならファイル間で変数を参照するよりも、デフォルト引数を使うなり、関数を作る関数を書くなりすればいいのでは?

1. デフォルト引数を使う

デフォルト引数は、引数が渡されなければ初期値にセットされます。

func_test.py
def calc_times(args, x=0):
    if x != 0:
        return args * 2
    else:
        return 0
main.py
import func_test as fc

a = 1
x = 2

b_without_x = fc.calc_times(a)
print("b_without_x={} ".format(b_without_x))

b_with_x = fc.calc_times(a, x)
print("b_with_x={} ".format(b_with_x))

2. 関数を作る関数を使う

高階関数で値を注入した関数を作ることができます。

func_test.py
def build_calc_times(x):
    def calc_times(args):
        if x != 0:
            return args * 2
        else:
            return 0
    return calc_times

calc_times = build_calc_times(0)
main.py
import func_test as fc

a = 1
x = 2
calc_times_with_x = fc.build_calc_times(x)

b_without_x = fc.calc_times(a)
print("b_without_x={} ".format(b_without_x))

b_with_x = calc_times_with_x(x)
print("b_with_x={} ".format(b_with_x))
1Like

@uasi

"本当にやりたいことは「関数の引数の数は変えないで、関数の挙動を外から変えられるようにする」ではないでしょうか?"
⇒おっしゃる通りです。関数を作る関数であれば、やりたいことを実現できそうです。その考え方はしらなかったです。とても参考になりました。ありがとうございます。

すみません、意見交換といいつつも、質問になってしまいました。もっとやりたいことなどの条件を明確にする必要がありますね。

0Like

Your answer might help someone💌