web-dev-qa-db-ja.com

「グローバル」を使用せずに関数外の関数変数にアクセスする

Pythonの関数外のローカル関数変数にアクセスしようとしています。たとえば、

bye = ''
def hi():
    global bye
    something
    something
    bye = 5
    sigh = 10

hi()
print bye

上記は正常に機能します。 global byeを使用せずにhi()の外でbyeにアクセスできるかどうかを知りたいので、私は試しました:

def hi():
    something
    something
    bye = 5 
    sigh = 10
    return

hi()
x = hi()
print x.bye 

上記はAttributeError: 'NoneType' object has no attribute 'bye'を与えます。

次に、私は試しました:

def hi():
    something
    something
    bye = 5
    sigh = 10
    return bye 
hi()
x = hi()
print x.bye

今回はエラーすら与えません。

それで、グローバルを使用せず、変数byeも出力せずに、関数(hi())の外側のローカル関数変数(sigh)にアクセスする方法はありますか? (質問は、以下の@hcwhsaのコメントの後にsighを含めるように編集されました。

32
user2480526

この行に沿って何かを行うことができます(Python v2.7.15とv3.7.1の両方でテストしましたが、それらをテストしました):

def hi():
    # other code...
    hi.bye = 42  # Create function attribute.
    sigh = 10

hi()
print(hi.bye)  # -> 42

関数はPythonのオブジェクトであり、任意の属性を割り当てることができます。

この種のことを頻繁に行う場合は、装飾された関数への各呼び出しにthis引数を追加する関数デコレーターを作成することにより、より汎用的なものを実装できます。

この追加の引数は、関数に定義に明示的に埋め込む(ハードコードする)必要なしに関数を参照する方法を提供し、クラスメソッドが通常selfという名前の最初の引数として自動的に受け取るインスタンス引数に似ています。混乱を避けるために異なるものを選びましたが、self引数のように、好きな名前を付けることができます。

そのアプローチの例を次に示します。

def with_this_arg(func):
    def wrapped(*args, **kwargs):
        return func(wrapped, *args, **kwargs)
    return wrapped

@with_this_arg
def hi(this, that):
    # other code...
    this.bye = 2 * that  # Create function attribute.
    sigh = 10

hi(21)
print(hi.bye)  # -> 42
73
martineau

問題は、xを文字列として設定した後にprint x.byeを呼び出していたことです。 x = hi()を実行すると、hi()が実行され、xの値が5に設定されます(byeの値。bye変数自体への参照としてxの値は設定されません)。例:bye = 5; x = bye; bye = 4; print x;は4ではなく5を出力します

また、hi()を2回実行する必要はありません。x = hi()ではなくhi();x=hi()を実行します(以前の方法ではhi()を実行し、結果の値5で何もしませんでした) 、そして同じhi()を再実行し、5の値をx変数に保存します。

したがって、完全なコードは

def hi():
    something
    something
    bye = 5
    return bye 
x = hi()
print x

複数の変数を返す場合は、必要に応じてリストまたは辞書を使用することが1つのオプションになります。

例:

def hi():
    something
    xyz = { 'bye': 7, 'foobar': 8}
    return xyz
x = hi()
print x['bye']

http://docs.python.org/2/tutorial/datastructures.html#dictionaries のpython辞書の詳細

8
John
 def hi():
     bye = 5
     return bye  

print hi()
1
Allan Mwesigwa

あなたはこの線に沿って何かをすることができます:

def static_example():
   if not hasattr(static_example, "static_var"):
       static_example.static_var = 0
   static_example.static_var += 1
   return static_example.static_var

print static_example()
print static_example()
print static_example()
0
Thomas Corll

同じ問題が発生しました。あなたの質問への回答の1つは、次のアイデアにつながりました(最終的にはうまくいきました)。 Python 3.7を使用します。

    # just an example 
    def func(): # define a function
       func.y = 4 # here y is a local variable, which I want to access; func.y defines 
                  # a method for my example function which will allow me to access 
                  # function's local variable y
       x = func.y + 8 # this is the main task for the function: what it should do
       return x

    func() # now I'm calling the function
    a = func.y # I put it's local variable into my new variable
    print(a) # and print my new variable

次に、このプログラムをWindows PowerShellで起動し、答えを取得します。4.結論:ローカル関数の変数にアクセスできるようにするには、ローカル変数の名前の前に関数の名前とドットを追加します(そしてもちろん、この構造を使用して、関数の本体と外部の両方で変数を呼び出します)。これが役立つことを願っています。