Python 板


LINE

Python一個很方便的功能是函數可以當作參數傳遞 那請問我可以在class裡面取得調用的函數物件嗎 例如我想做到在函數被調用前 可以做其他處理 拿print來舉例好了 像是下面程式碼這樣 class Logger(object): def int(self, value): print('Call int()') return int(value) def float(self, value): print('Call float()') return float(value) logger = Logger() logger.int('123') logger.float('123') 我只知道可以用下面的方法取得函數的名稱 class Logger(object): def __getattr__(self, name): print('Call %s()' % name) 但是函數物件要怎麼抓? 像是如果我有20個函數的話 那class裡面就要寫20遍 如果之後又需要擴充到40個函數 那就還要在class裡面加40個 有沒有什麼方法是可以把logger.func()裡的func()直接抓來用的 例如什麼 class Logger(object): def __getfunc__(self, func, arg): # do something return func(arg) 之類的 這樣我只要定義一個函數 後面不過擴充幾個需要做一樣處理的函數 我都不需要再增加class裡面的函數數量 感謝 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.184.77.196 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/Python/M.1598058491.A.1F6.html ※ 編輯: XperiaZ6C (111.184.77.196 臺灣), 08/22/2020 09:11:06
1F:→ gmccntzx1: 你的意思是,每當一個 member method 被呼叫時,就要08/22 09:23
2F:→ gmccntzx1: 抓到是誰被呼叫嗎?08/22 09:23
3F:→ gmccntzx1: 如果要的效果是這樣,我目前是有想到可以透過 metacla08/22 09:25
4F:→ gmccntzx1: ss 去做08/22 09:25
也不算是member method被呼叫 因為像是int()一開始是沒有定義在class Logger裡面 之所以會在裡面定義是因為要在直接執行int()前做一些處理 假設今天有個函數是 ringing(1) 那我不用管這個函數實際做了什麼 我只要用 logger.ringing(1) 這樣去呼叫它 這個Logger class就會在執行完預處理後直接return ringing(1) 像是上面的概念這樣 class Logger(object): def __getfunc__(self, func, arg): # do something return func(arg) ※ 編輯: XperiaZ6C (111.184.77.196 臺灣), 08/22/2020 09:51:15
5F:→ gmccntzx1: 我釐清一下你想做的事:也就是說,任何一個沒有定義在08/22 09:58
6F:→ gmccntzx1: Logger class 裡的 function ‘foo’,只要透過 logg08/22 09:58
7F:→ gmccntzx1: er.foo() 這種方式呼叫,你就可以先透過 logger 去做08/22 09:58
8F:→ gmccntzx1: 你想做的事再讓那個 function 做自己的事囉?08/22 09:58
9F:→ gmccntzx1: 先說好了,如果要透過這種呼叫方式來達到這種功能是有08/22 10:06
10F:→ gmccntzx1: 點奇怪。雖然說你可以硬是透過 `__getattr__()` 讓08/22 10:06
11F:→ gmccntzx1: logger 在找不到 member method 時(也就是上述的情況08/22 10:09
12F:→ gmccntzx1: ),去其他 scope 找你要的 function ,如 globals()08/22 10:11
13F:→ gmccntzx1: 。但是這樣你就要自己處理 name resolution 的問題。08/22 10:12
14F:→ gmccntzx1: 再來,怎麼取得 caller 的 arguments 又是另一個問題08/22 10:13
15F:→ gmccntzx1: 但是如果你沒有需要處理 caller arguments 的話,那上08/22 10:19
16F:→ gmccntzx1: 面那個問題就省了08/22 10:19
17F:推 skyconquer: 我回了一篇文在底下,請參考看看。08/22 10:27
18F:推 TitanEric: 怎麼覺得跟decorator有關08/22 10:37
19F:→ gmccntzx1: 我是這樣覺得,但目前還不清楚原 PO 真正的問題08/22 10:39
20F:→ gmccntzx1: 怕變成 XY problem08/22 10:40
21F:→ gmccntzx1: 先給原 PO 看看這個是不是你想要的結果:08/22 10:45
22F:→ gmccntzx1: https://pastebin.ubuntu.com/p/vnYCs4PxtZ/08/22 10:45
感謝您的詳細解說 讓我發現我整個會錯意了 因為函數並不是定義在global 或是 local scope 而是客戶給的一個Java Code裡面 我這邊是要用RPC去呼叫 這樣好像是根本找不到function沒錯 客戶給的Java code會像這樣 package com.example.java.rpc; public class JavaCode implements RpcInterface { public boolean click() { // do something } 而我Python端可以繼承現有的RpcInterface 然後給他Java的package name 就能產生一個接口去呼叫Java裡面的函數 class UseJavaCode(RpcInterface): def test_java_code(self): self.java = self.load_interface('com.example.java.rpc') self.java.click() 而我這邊是希望寫一個Python wrapper去把這個interface包起來 在呼叫Java之前做一些處理 class Wrapper(object): def __init__(self, rpc): self.java = rpc.load_interface('com.example.java.rpc') def click(self): # do something return self.java.click() class UseJavaCode(RpcInterface): def test_java_code(self): self.java = Wrapper(self) self.java.click() 但是這樣客戶以後擴充他的Java code 我這邊的Python wrapper就也要跟著擴充 所以才想說有沒有辦法直接抓到class.func()的.func()進來到class裡面跑 像是 class Wrapper(object): def __init__(self, rpc): rpc.java = load_interface('com.example.java.rpc') self.java = rpc.java def __getfunc__(self, func): # do something return self.java.func() 抱歉造成大家誤解了QQ ※ 編輯: XperiaZ6C (111.184.77.196 臺灣), 08/22/2020 11:51:58 ※ 編輯: XperiaZ6C (111.184.77.196 臺灣), 08/22/2020 11:54:09 ※ 編輯: XperiaZ6C (111.184.77.196 臺灣), 08/22/2020 12:06:14
23F:→ gmccntzx1: 試試看這是不是你要的效果:08/22 12:30
24F:→ gmccntzx1: https://pastebin.ubuntu.com/p/MjrW628M7k/08/22 12:30
25F:→ gmccntzx1: 但是這個做法就如同前面提到的,若你需要處理 caller08/22 12:31
26F:→ gmccntzx1: arguments 的話,還要額外透過 frame 去抓資訊08/22 12:31
27F:→ gmccntzx1: 另一個做法是改成用 function wrapper 把每一個 rpc08/22 12:33
28F:→ gmccntzx1: 提供的 function 都包過一次,這種方法對於也要處理08/22 12:33
29F:→ gmccntzx1: arguments 的話會比較方便,但是缺點就是一旦 wrapper08/22 12:34
30F:→ gmccntzx1: 太多,要轉進呼叫到實際上 rpc 的 function 也需越多層08/22 12:34
31F:→ gmccntzx1: 接續上面第一種方式,也可以不透過 frame 去抓 caller08/22 12:58
32F:→ gmccntzx1: argument08/22 12:58
33F:→ gmccntzx1: https://pastebin.ubuntu.com/p/HpXBF4cNgy/08/22 12:58
非常感謝您! 第二個方法看起來可以解決這個問題 再次感謝 ※ 編輯: XperiaZ6C (111.184.77.196 臺灣), 08/22/2020 13:27:21
34F:→ gmccntzx1: (`・∀・)b 08/22 17:27
35F:→ azuel: 看了這些討論之後我覺得自己好菜 08/23 18:03
36F:推 gmccntzx1: @azuel 不用這樣說,每個人都嘛是從新手開始走起。覺 08/23 20:51
37F:→ gmccntzx1: 得自己不足的時候,就繼續努力把能力練起來,這才是該 08/23 20:51
38F:→ gmccntzx1: 做的事。而且說實在的,我也沒有解決了什麼高深的問題 08/23 20:51
39F:→ gmccntzx1: ,純粹只是分享以我目前所知所能構成的解法。以後對 P 08/23 20:51
40F:→ gmccntzx1: ython 了解更透徹後,說不定又會有更好的解法。共勉之 08/23 20:51







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:e-shopping站內搜尋

TOP