Python 通過字符串調用類方法或方法

  • 問題描述

今天遇到個問題,在一個類裏面,想要通過字符串調用類裏面的方法,即(注意,以下爲錯誤代碼演示,只是爲了表述問題):

class A(object):
	def a(self):
		print('xxxxx')

	def b(self):
		c= 'a'
		self.c()

test = A()
test.b()

 如上面代碼所示,在b函數裏面,我將字符 a 賦值給了 c ,然後在後面,想要通過 self.c() 的方式,來替代 self.a(),完成對 a 函數的調用。當然,上面的代碼毫無疑問的報錯了,那麼,怎麼才能通過字符串調用類裏面的函數呢?

  • 解決方法

首先,來解決類裏面通過字符串來調用函數的問題,其實也很簡單,我們需要用到一個稍微高階一點的Python自帶函數: getattr()

直白的說,這個函數是獲取一個實例(也可以說是類)裏面的屬性或方法。用法爲:

getattr(object, name[, default])

           第一個object參數爲: 傳入一個實例或者類

           第二個name參數爲:  你想要獲得的這個類或實例裏面的屬性或方法的名稱

           第三個參數default爲: 如果沒有在這個類或實例裏面找到對應的屬性或方法,應該返回什麼。

           如果想要詳細瞭解這個內建函數的使用方法,請看:Python getattr() 函數 | 菜鳥教程

           這裏舉個例子:

class A(object):
	def a(self):
		print('sfsdf')

test = A()
print(getattr(test, 'a', 'None'))
print(getattr(test, 'b', 'None'))

 運行結果如下:

 

 從上面的代碼,我們可以看到,getattr()函數獲得了 test 實例裏面的 a 方法,然後將該方法打印了出來,我們還想獲取 test 實例的 b 方法, 但是 test 實例並沒有 b 方法,所以就返回了我們預先指定的 None。這就是getattr() 函數的用法。說到這裏,相信不少童鞋已經知道怎麼通過字符串調用類方法了,完整代碼如下:

class A(object):
	def a(self):
		print('GodLordGee')

	def b(self):
		c= 'a'
		func = getattr(self, c, None)
		func()

test = A()
test.b()

 

如上,我們就可以通過字符串,調用類裏面的方法了。

也許很多童鞋能夠理解這個內建函數的用法,但是卻不知道這個函數的實際使用場景,那麼我可以在這裏給你提供一個使用場景:

    你寫了一個類,類裏面有很多個功能函數,還有一個主函數。在主函數裏面,會傳進來不同的字符串,這些字符串表示程序想要調用的方法。例如:主函數傳進來一個 ‘start’ 字符串,表示程序現在要調用start函數;又過了一會,主函數傳進來了一個 'pause' 字符串,表示程序現在想要調用pause函數;再過了一會,主函數傳進來了一個‘stop’ 字符串,表示程序現在想要調用stop函數。那麼,如上所述的一個過程,我們只需要一個getattr()函數,就可以很方便的調用類裏面的各種方法。

 

  • 擴展知識

知道了如何通過字符串調用類裏面的方法,那麼,如果通過字符串直接調用方法呢?這裏有三個函數可以幫助我們實現這個功能(eval、locals、globals):

>>> def a():
	print('I am a')

	
>>> def b():
	print('I am b')

	
>>> eval('a')
<function a at 0x000002C526C81C80>
>>> eval('a')()
I am a
>>> eval('b')()
I am b
>>> locals()['a']()
I am a
>>> locals()['b']()
I am b
>>> globals()['a']()
I am a
>>> globals()['b']()
I am b
>>> 

 

相信通過上面的代碼,大家已經知道如果通過字符串調用方法了。如果想要詳細瞭解上述三個函數的具體用法,請谷歌百度哦~

Tips:儘量不要使用eval函數,因爲eval is evil。使用這個函數是不安全的,自己用還好,但如果是搭建了個服務器什麼的,別有用心的人上傳上來惡意代碼,你的程序用eval一執行,那豈不是GG ?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章