インスタンスを使用してクラスのプロパティを参照すると、動的バインディングが発生します。つまり、pythonは、インスタンスがクラス属性を参照するたびに、対応するクラス属性をインスタンスにバインドします。
動的バインディングの例:
classA:
def test1(self):print("hello")
def test2(self):print("world")
def bound():
a =A()
a.test1()
A.test1 = A.test2
a.test1()if __name__ =="__main__":bound()
出力結果:
hello2 world
上記のコードからわかるように、クラスメソッドの変更は、インスタンスによるメソッドの呼び出しにリアルタイムで影響します。これは、pythonがインスタンスによるメソッドの呼び出しプロセスでクラスメソッドを動的に検出することを示しています。
動的バインディングのコスト:
classA:
def test(self):
pass
def one_loop(limited_time):
a =A()for i inrange(limited_time):
a.test()
f = a.test
for i inrange(limited_time):f()
上記の2つのループでは、1つはa.test()を呼び出して動的バインディングを継続的に実行し、もう1つは最初にa.testをfに割り当てます。動的バインディングは1つだけです。2つのループのタイミングをとることにより、動的バインディングがテストされます。価格。
出力結果:
1 [0.0, 0.0, 0.0, 0.0, 0.0, 0.0009999275207519531, 0.008995771408081055, 0.19991111755371094, 1.2715933322906494, 15.831915855407715]
2 [0.0, 0.0, 0.0, 0.0, 0.0, 0.12503726671039295, 0.09472344399590288, 0.1999776288967874, 0.131608969147562, 0.1553209370384522]
線グラフの横軸はlog10(サイクルタイム)、縦軸は秒です。
出力データでは、最初の行は動的バインディングと1回限りのバインディングに費やされた時間の差であり、2番目の行は合計動的バインディング時間の差の比率です。
周波数が非常に小さい場合、基本的に両者に差がないか、ごくわずかであることがわかります。
10 ^ 7サイクル、つまり数千万サイクル後、動的バインディングと静的バインディングの間にかかる時間には大きな違いがあります。サイクル数が10億に達すると、時間のかかる差は15秒にもなります。合計時間の15%を占めました。
以上のことから、動的バインディングの効率は静的バインディングの効率よりも低いことがわかりますが、バインディングのコストは非常に時間がかかるため、基本的に回数が少ない場合は効果がありません。
動的バインディングの利点:
classA:
def test_hello(self):print("hello")
def test_world(self):print("world")
def main():
s =A()
# 早期バインディング
f = s.test_hello
# 変更方法
A.test_hello = test_world
f()
# 動的バインディング
s.test_hello()if __name__ =="__main__":main()
出力結果:
hello2 world
クラスメソッドの変更はリアルタイムで動的バインディングに反映でき、クラスメソッドの変更は早期バインディングでは認識できません。
総括する:
ワンタイムダイナミックバインディングのコストは非常に小さいです。バインディングの数が少ない場合、効率は基本的に影響を受けず、バインディングの数が1,000万に達すると影響は大きくなります。
動的バインディングのリアルタイム追跡クラスメソッドの変更、柔軟性の向上。
以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。
Recommended Posts