

pythonの初心者です。  
以下のように複数のmoduleをimportし、それをforの中で利用したいのですが、値の渡し方を調べてみましたが、見つけられません。  
ご教授おねがいします。

以下では複数の画像をmoduleを使って処理してます。  
この際にimg, nameなどがmodule Aに、またfunc_1.Aで作成したdirectoryやfileがmodule Bに渡せません。

どうすればすれば良いのでしょうか。（name-spaceの問題でしょうか。）  
またこの場合の引数の書き方がよくわからないのと、戻り値をどうしたら良いのかわかりません。  
forの下に必要な関数を書いて、１つのfileにすれば実行できそうですが、関数が多くて長いので、それは避けたいです。

作業内容：

[code]

    import os
    import glob
    from PIL import Image
    ....
    import module A
    import module B
    import module C
    ....
    
    ## 全data読み込み
    file = glob.glob('dir-name/*.png')
    
    ##dataごとの作業
    for path in file :
        name= os.path.splitext(os.path.basename(path))[0]
        img = Image.open(path)
        
        A.func_1(img,name)
        B.func_2(img_dir0)
        C.func_3(img_dir1)
    ....    
    
[/code]

module A.pyの内容：

[code]

    import os
    from PIL import Image
    ....
    
    def func_1(img, name) :
    
        # create directory
        img_dir0 = './images/'+ '1_'+ name+ '/1_crop/'
        if not os.path.exists(img_dir0):
             os.makedirs(img_dir0)
        
        # get size
        W = img.width
        H = img.height
        # crop
        Ax=10
        Ay=15
        img1_ = img.crop((Ax, Ay, Ax+512, Ay+512)) 
        
        # dataを小さく切り出してゆく。
        for i in range(0,12):
            ##indexを2桁にする
            N = '{0:02d}'.format(i)
    
            if i < 4 :
                #print('1st row : i = ', i)
                img1_1 = img1_.crop((0 + i*128,  0,  128 + i*128, 128))
                img1_1.save(img_dir0 + N + ".png")
                .....
        return img_dir0
    
[/code]

module B.pyの内容：

[code]

    import os
    import glob
    from PIL import Image,ImageOps
    ....
    
    def func_2(img_dir0) :
        
        # create directory
        img_dir1 = img_dir0 + '2_inv/'
        if not os.path.exists(img_dir1):
            os.makedirs(img_dir1)
    
        # read date creaed by func_1
            file = glob.glob(img_dir0 + "*.png")
    
        #画像処理：反転etc
        for path in file :
            im_invert = ImageOps.invert(path)
            im_invert.save(img_dir1 + name + '_inv.png')
            .....
       return img_dir1
    
[/code]

module Bで、module
Aの戻り値を指定しているんですが、うまくゆきません。ご指摘のように「A.func_1の戻り値が必要ならば、2行にして作業用変数も用意しておく
」と思われますが、どのようにすればよいのでしょうか。

[code]

    "NameError: name 'img_dir0' is not defined"
    
[/code]

わかりました。  
戻り値を受け取る作業変数を用意すればよいのですね。

ただ今度はBでiterationで使ったname（fileの名前）を受け取れないのですが、これもA.func_1の戻り値として指定する必要があるのでしょうか。

引数に加えればよいだけですね。

[code]

    ##dataごとの作業
    for path in file :
        name= os.path.splitext(os.path.basename(path))[0]
        img = Image.open(path)
        
        A.func_1(img,name)
        img_dir0 = A.func1(img, name)
    
        B.func_2(img_dir0, name)
        img_dir1 = B.func2(img_dir0, name)
    
        C.func_3(img_dir1)
        varC = func.C(img_dir1)
    
[/code]


CC BY-SA 4.0
2020-10-18T06:03:56.800
71298
2020-10-18T15:49:32.940
2020-10-18T15:49:32.940
42362
42362
question
python python3
Python 3.7で複数のmoduleをimportし、iteration の中で各moduleに値を渡したい


素直に`func_1`の戻り値としてフォルダ名の変数値(この場合は`img_dir0`)を返し、それを`func_2`のパラメータに指定すれば良いでしょう。

  * `A.py`の`func_1`の最後で`return img_dir0`とする
  * メインプログラムで`B.func_2(A.func_1(img,name))`とすれば1行で両方を呼び出せて、戻り値を覚えておくための作業用変数も不要になる  
メインプログラムの別の処理で`A.func_1`の戻り値が必要ならば、2行にして作業用変数も用意しておく

* * *

ちなみに質問記事のソースコードは、いろいろと不足していたり間違っていたりするので、そのままでは動作しません。(なおパラメータの受け渡しだけチェックするためにPILの細かい処理は削って動かしたので、そのへんはチェックしていません)

  * メインプログラム

    * import glob が不足
    * `glob.blob`は`glob.glob`のスペルミス
    * `func_1.A`と`func_2.B`は、名前の`.`の前後が逆で、`A.func_1`と`B.func_2`が正しい
  * A.py

    * `func_1`のデフォルト値付き引数のデフォルト値が、無効な値(未定義の変数)になっている  
`=XXX`は不要で引数だけ定義して`def func_1(img, name):`とすれば良い

  * B.py

    * import glob が不足

    * `func_2`のデフォルト値付き引数のデフォルト値が、無効な値(未定義の変数)になっている  
`A.py`の`func_1`と同様`def func_2(img_dir0):`とすれば良い

    * `img_dir1 = img_dir0 + '/2_inv/'`の`'/2_inv/'`の前の`/`は不要で`'2_inv/'`とした方が良いのでは？

    * その下の3行分くらいインデントがおかしいですが、転記ミスでしょう。

* * *

**コメント、追記への対応：**

`A.func_1` → `B.func_2` →
`C.func_3`がそれぞれ前の関数の戻り値を次の関数のパラメータにして呼び出しているなら、以下のような1行で行えます。

[code]

    C.func_3(B.func_2(A.func_1(img,name)))
    
[/code]

それでは判り難いとか、考え方が見えないという場合、以下のように考えてください。

変数の名前というのは、それを扱える有効な範囲というものがあって、スコープと呼ばれます。

例えば`A.func_1()`の`img_dir0`や`B.func_2()`の`img_dir1`という変数およびその名前はそれぞれの関数の中だけで有効になります。

`A.func_1()`で`return
img_dir0`と戻り値を返しても、`A.func_1()`から戻ってきたメインプログラムでは`img_dir0`という名前の変数は使えません。

どうするかと言えば、`A.func_1()`の戻り値を受け止めるメインプログラム側の変数を用意して、そこに格納しておくわけです。

メインプログラム側の変数は他と衝突しなければ、同じ名前を定義してもかまいません。

そうやって次の関数のパラメータに指定し、また戻ってきた値を変数に入れて次の関数のパラメータに指定するという連鎖にするわけです。

[code]

    img_dir0 = A.func_1(img,name)
    img_dir1 = B.func_2(img_dir0)
    img_dir2 = C.func_3(img_dir1)
    
[/code]

* * *

**更に追記：**

`B.func_2()`に対して`name`パラメータを指定する件ですが、`A.func_1()`に使った`name`パラメータと同じならば、`B.func_2(img_dir0,name)`のように使い回してそれを指定すれば良いでしょう。

`A.func_1()`の中で作った、少しずつ切り出した`N`の名前というのなら、そもそも`img_dir0`フォルダ内にあるファイル名を取得して処理しているので、メインプログラムでやっているようにその`path`から切り出せるでしょう。

[code]

    for path in file:
        name= os.path.splitext(os.path.basename(path))[0]
        im_invert = ImageOps.invert(path)
        im_invert.save(img_dir1 + name + '_inv.png')
    
[/code]


CC BY-SA 4.0
2020-10-18T10:38:58.783
71305
2020-10-18T14:07:21.260
2020-10-18T14:07:21.260
26370
26370
71298
answer