2016-11-12 4 views
2

以下のケースでPythonの動作がどう違うのだろうか?Pythonで "ローカルオブジェクト"を作る方法は?

ケース1ローカル整数変数を変更しますが、グローバル変数は変わりません。まあ、それはOKです。

N = 1 

def Func1(x): 
    x = 0 

Func1(N) 
print(N) # prints 1 

ケース2私は、ローカルオブジェクトのプロパティを変更...そして私がグローバルオブジェクトを変更したようです。

class C1: 
    def __init__(self): 
     self.A = 1 

Obj1 = C1() 

def Func2(x): 
    x.A = 0 #here is a confusing moment 

Func2(Obj1) 
print(Obj1.A) #prints 0 

多分私は実際にローカルであるかどうかについての不完全な理解を持っていますか?その場合、「ローカルオブジェクト」に類似したものをどのようにコーディングできますか?

+3

グローバルオブジェクトは変更していません。グローバルオブジェクト内のデータを変更しました。 – Matthias

+0

グローバルオブジェクトのようなものを作成するにはどうすればよいですか? – Bzhenko

答えて

0

関数の引数は、という代入で渡されるです。 [1] そして、Pythonでは、オブジェクトは代入時にコピーされません。 は、だからあなたの第二の例では、オブジェクトのローカルコピーを呼んでいるものにするために、あなたはcopy.deepcopy(x)を使用して、インスタンスのために、明示的にそれをコピーする必要があります[2]

だからあなたの第二のコードはなる:

import copy 
class C1: 
    def __init__(self): 
     self.A = 1 

Obj1 = C1() 

def Func2(x): 
    x = copy.deepcopy(x) # Make a local copy of the object 
    x.A = 0 #No more confusion 

Func2(Obj1) 
print(Obj1.A) #prints 1 

[1] https://docs.python.org/3.4/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference

を[2] https://docs.python.org/3/library/copy.html

0

あなた比較りんごオレンジ(またはものは何でも言うたい)へ。最初のケースでは、関数内のグローバル変数の値を変更しようとしていました。 Pythonは代入で変数を渡すので、関数を呼び出したときにグローバル変数は変更されませんでした。。私たちはあなたの最初のケースに割り当てによって渡すときに何が起こるかを確認します

>>> N = 1 
>>> def foo(x): 
    x = 0 
    return x 

>>> foo(N) # this will not change N. we need to pass N by assingment 
0 
>>> N 
1 
>>> N = foo(N) # this will change N 
>>> N 
0 
>>> 

この動作はPython3 FAQで文書化されています

引数はPythonの代入によって渡されることに注意してください。代入はオブジェクトへの参照を作成するだけなので、呼び出し元と呼び出し先の引数名の間にエイリアスは存在しないので、参照による呼び出し自体はありません。

強調は私のものです。

2番目のケースでは、グローバル変数の値を変更しませんでした。 Obj1は変数ではないオブジェクトです。 Obj1の属性をObj1ではなくに変更しました。 Obj1を参照渡ししようとするとどうなるかを確認してください。

>>> class CL: 
    def __init__(self): 
     self.A = 1 


>>> Obj1 = CL() 
>>> def foo(x): 
    # lets try chaning the actual value that Obj1 holds 
    x = None 


>>> foo(Obj1) # did it change? 
>>> Obj1 
<__main__.CL object at 0x03B29B50> 
>>> # Nope 
関連する問題