困惑
在之前用sgmllib解析網頁的時候遇到了·def do_a(self,attr)·這類的函數,可以自動識別<a>並解析其中內容。 在看learningpythonthehardway時也遇到了render.index()之類的隨着url路由而變化的函數名。 遂思考,怎么才能實現這種動態的函數名呢?
研究
在使用Java、C、C#等其他語言時,並沒有這類的功能。有可能是python獨有功能,遂百度,未發現相關介紹。 python為動態語言,且為面向對象語言,一切為對象。函數也是一個對象,那么函數也應該可以像普通的變量一樣,增加一個引用。
測試
例1
import sys class A: def __init__(self,str): self.str=str setattr(self.__class__,self.str,self.test) def test(self): print sys._getframe().f_code.co_name print self.str if __name__=='__main__': a=A("haha") a.haha()
結果:
test haha
例2
dynamicfunction.py
import sys names=locals() #print locals() str1='' def test(str): global str1 str1=str names[str1]=test2 def test2(): print sys._getframe().f_code.co_name print str1
結果:
test2 haha
解釋
例1,定義一個A類,然后實例化一個A對象,通過setattr函數來給當前類添加一個變量,值是test函數。調用haha函數,就相當於調用了test函數。 例2,定義一個模塊,通過另一個模塊函數調用函數來增加變量,值是test2函數。調用haha函數,就相當於調用了test2函數。
原理
python系統會維護一個變量的字典,可以通過locals()或者globals()獲取到該字典。由於字典是可變對象,那么,就可以動態的增加變量。由於函數也是一個對象,那么就可以將變量指向函數。這樣就可以達到動態修改函數名的目的了。
例子
locals()
結果:
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
locals()['a']=1a
結果:
1