デフォルトのパラメータを持つ関数について質問があります。
import sys
from random import randint
my_list = [1,2,3]
def Veli(a, b = my_list):
my_list.append(randint(1,1500))
print a + b[-1]
print "Number of Refs:", sys.getrefcount(my_list)
print "Def args:", Veli.func_defaults
Veli(1) # This is 4
Veli(1) # We almost always obtain different result because of randint
Veli(1) # Again different results.
print Veli.func_defaults
print "Number of Refs:", sys.getrefcount(my_list)
Veli(1)
my_list = [-5] # old my_list has different address
print "Number of Refs:", sys.getrefcount(my_list) # Less than previous
print "Def args:", Veli.func_defaults
Veli(1) # Now gives same results.
print "Def args:", Veli.func_defaults
Veli(1) # Same result again...
出力:(もちろん、いくつかの数値は、randintが返した値によって異なります。)
参照数:3
Def args:([1、2、3]、)
322
1119
740
([1、2、3、321、1118、739]、)参照
数:3
303参照
数:2
Def args :([1、2、3、321、1118、739、302]、)
303
Def args:([1、2、3、321、1118、739、302]、)
303
次のコードは、bとmy_listが同じアドレスを参照しなくなったため、前のコードよりも少ない数になります。
print "#ref:", sys.getrefcount(my_list) # Less than previous
これで、関数のデフォルトの引数であるbに到達する方法(唯一の方法は?)があります。
Veli.func_defaults[0]
長い説明でごめんなさい。これが私の質問です:
これは問題ですか?私のモジュールのディクショナリはmy_list変数をクラッシュさせ、my_list変数は以前よりもデフォルトのアドレスを持つようになりました。次に、my_listという名前のグローバル変数を本体で使用する関数が変更されます(成長します)が、デフォルトの引数は変更されません。式の実行時に名前が
b
付けられたグローバル変数が表示されないのはなぜですか?私は知っています、my_listとは異なるアドレスを持っています(相互オブジェクト(listなど)は異なる、一意の、新しく作成されたリストを参照することが保証されているため)が、bが関数の引数であるときにグローバル変数を表示できないようにPythonが実装されたのはなぜですか?包括的に説明していただけますか?my_list
a + b[-1]
b
b
Veli.func_defaults [0]で同じ結果を得る方法はありますか?このコードを実行してから、Veliという名前の関数のデフォルトの引数を変更したいとします。my_listとbのアドレスが異なるため、my_listではこれを行うことができません。1つの方法は、リストの要素Veli.func_defaults[0]を変更することです。別の方法はありますか?
(上記のコードとはあまり関係ありません)変数のアドレスを取得するにはどうすればよいですか?たとえば、?のアドレスを取得するにはどうすればよい
b
ですか?などの組み込み関数を使用して__hash__
いますが、もっと適切な方法があるはずです。
ノート:
a)このコードはどういうわけか役に立たないかもしれませんが、私は意見を学びたいです。
b)Python 2.6.6(r266:84292、2010年9月15日、15:52:39)linux2
上の[GCC 4.4.5]