45523


あるコードを実行したくて、変数の取得方法がわからなかったのでので簡易化したコードで質問します。  
参考書を見て、「global変数を使うことで、関数内からグローバル変数にアクセスできる」」ということは理解しているのですが、

[code]

    def f(x):
        global y
        y=x+2
        return x+2
    
    x=2
    print(y)
    >>4
    #誤ったコードです。実行されません。（イメージ的にこうなってほしい、みたいな・・？）
    
[/code]

のように、逆に関数内部の変数をグローバル変数として関数外部から取り出すことは不可能ですか？

P.S.)本当にしたかったこと

[code]

    class Queue:#練習用にQueueの一部機能を手書きしています。
        def __init__(self):
            self.items=[]
    
        def is_empty(self):
            return self.items==[]
    
        def enqueue(self,item):
            self.items.insert(0,item)#enqueuメソッドの引数itemをキューの一番最初（インデックス値＝０）の要素として追加します。
            #insertメソッドは、".insert(index値,要素)"によってリストにオブジェクトを追加します。
    
        def dequeue(self):
            return self.items.pop()
    
        def size(self):
            return len(self.items)
    
    import time
    import random
    
    def simulate_line(till_show,max_time):
        pq=Queue()
        tix_sold=[]
    
        for i in range(100):
            pq.enqueue("person" + str(i))
    
        t_end=time.time()+till_show
        now=time.time()
        while now<t_end and not pq.is_empty():
            now=time.time()
            r=random.randint(0,max_time)
            time.sleep(r)
            person=pq.dequeue()
            print(person)
            tix_sold.append(person)
    
        return tix_sold
    
    sold=simulate_line(5,1)
    print(tix_sold)
    
[/code]

のコードにおいて、tix_soldのリストの個数が１０個を超えるまで関数を繰り返し実行するようにしたかったです。


CC BY-SA 4.0
2018-07-11T15:54:24.367
45521
2018-07-12T07:28:44.840
2018-07-11T16:05:38.523
29238
29238
question
python
global変数の使い方について


> 逆に関数内部の変数をグローバル変数として関数外部から取り出すことは不可能ですか？

その関数を実行すれば、グローバル変数にアクセスすることは可能です。

`global y`は、`f(x)`を実行しないと定義されないため、  
以下のように`f(x)`を実行する必要があります。

[code]

    x=2
    f(2)
    print(y)  #=> 4
    
[/code]

そのため、`simulate_line`の場合、`simulate_line`自体を実行しているので、  
以下のように`global tix_sold`としておけば、エラーなく実行できるはずです。

[code]

    def simulate_line(till_show,max_time):
        pq=Queue()
        global tix_sold
        tix_sold=[]
        # 略
    
[/code]

ただし、バグを減らすためには、極力グローバル変数は避けたほうが良いため、今回の場合は、`simulate_line`の戻り値をそのまま利用したほうが良いと思います。


CC BY-SA 4.0
2018-07-11T16:12:39.410
45523
2018-07-11T16:42:29.557
2018-07-11T16:42:29.557
45521
answer


関数内部の変数をグローバル変数として関数外部から取り出すことは可能です。  
しかし、以下のようにしてしまうと、関数を繰り返し実行する毎に`tix_sold`が初期化されてしまいます。それで`if`を使って初期化されていない場合だけ初期化するようにするとかという複雑なことになります。

[code]

    def simulate_line(till_show,max_time):
        pq=Queue()
        global tix_sold
        tix_sold=[]
    
[/code]

クラスの勉強をしているようなので、ここはクラスの出番です。クラスを使って`tix_sold`をインスタンス変数にすると、初期化が簡単にでき、関数を繰り返し実行して`tix_sold`のリストに追加していく処理もでき、関数外部からも取り出すことができます。

[code]

    class simulate:
        def __init__(self):
            self.tix_sold=[]
    
        def simulate_line(self, till_show, max_time):
            pq=Queue()
            ----中略---
            self.tix_sold.append(person)
    
    sold = simulate() 
    sold.simulate_line(5,1)
    sold.simulate_line(6,1)
    print(sold.tix_sold)
    
[/code]


CC BY-SA 4.0
2018-07-12T03:09:09.563
45538
2018-07-12T07:28:44.840
2018-07-12T07:28:44.840
15171
15171
45521
answer