Python這類的動態語言大多提供Run-time時動態修改一個object的方法,這樣的好處是你可以動態的修改某個object,為這個Obejct加入一些新的method。
Ruby要為object加入新method非常簡單:
dog = Object.new def dog.sit print "I'm sitting.\n" end dog.sit
Ruby很簡單就能為dog加入一個sit的method。
Python實做起來稍微麻煩一些,主要原因是因為Python的函式有分成bound和unbound。
>>> def foo(): ... print "foo" ... >>> class A: ... def bar( self ): ... print "bar" ... >>> a = A() >>> foo <function foo at 0x00A98D70> >>> a.bar <bound method A.bar of <__main__.A instance at 0x00A9BC88>> >>>
bound method必須被bound到一個instance,在呼叫method時instance才會被當成參數傳入。
由於函式預設都是Unbound,如果直接加入method到object中,Python會丟出exception
>>> def barFighters( self ): ... print "barFighters" ... >>> a.barFighters = barFighters >>> a.barFighters() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: barFighters() takes exactly 1 argument (0 given)
其實只需要手動把method bound到instance上就可以解決這個問題。
這邊我們使用type module中的MethodType來把method bound到instance上。
>>> import types >>> a.barFighters = types.MethodType( barFighters, a ) >>> a.barFighters <bound method ?.barFighters of <__main__.A instance at 0x00A9BC88>> >>> a.barFighters() barFighters
可以看到method被bound後就可以在Python中被正確的呼叫,這就是Python動態在object加入method的方法。
沒有留言:
張貼留言