→ gmccntzx1: 你的意思是,每當一個 member method 被呼叫時,就要08/22 09:23
→ gmccntzx1: 抓到是誰被呼叫嗎?08/22 09:23
→ gmccntzx1: 如果要的效果是這樣,我目前是有想到可以透過 metacla08/22 09:25
→ 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
→ gmccntzx1: 我釐清一下你想做的事:也就是說,任何一個沒有定義在08/22 09:58
→ gmccntzx1: Logger class 裡的 function ‘foo’,只要透過 logg08/22 09:58
→ gmccntzx1: er.foo() 這種方式呼叫,你就可以先透過 logger 去做08/22 09:58
→ gmccntzx1: 你想做的事再讓那個 function 做自己的事囉?08/22 09:58
→ gmccntzx1: 先說好了,如果要透過這種呼叫方式來達到這種功能是有08/22 10:06
→ gmccntzx1: 點奇怪。雖然說你可以硬是透過 `__getattr__()` 讓08/22 10:06
→ gmccntzx1: logger 在找不到 member method 時(也就是上述的情況08/22 10:09
→ gmccntzx1: ),去其他 scope 找你要的 function ,如 globals()08/22 10:11
→ gmccntzx1: 。但是這樣你就要自己處理 name resolution 的問題。08/22 10:12
→ gmccntzx1: 再來,怎麼取得 caller 的 arguments 又是另一個問題08/22 10:13
→ gmccntzx1: 但是如果你沒有需要處理 caller arguments 的話,那上08/22 10:19
→ gmccntzx1: 面那個問題就省了08/22 10:19
推 skyconquer: 我回了一篇文在底下,請參考看看。08/22 10:27
推 TitanEric: 怎麼覺得跟decorator有關08/22 10:37
→ gmccntzx1: 我是這樣覺得,但目前還不清楚原 PO 真正的問題08/22 10:39
→ gmccntzx1: 怕變成 XY problem08/22 10:40
→ gmccntzx1: 先給原 PO 看看這個是不是你想要的結果: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
→ gmccntzx1: 試試看這是不是你要的效果:08/22 12:30
→ gmccntzx1: 但是這個做法就如同前面提到的,若你需要處理 caller08/22 12:31
→ gmccntzx1: arguments 的話,還要額外透過 frame 去抓資訊08/22 12:31
→ gmccntzx1: 另一個做法是改成用 function wrapper 把每一個 rpc08/22 12:33
→ gmccntzx1: 提供的 function 都包過一次,這種方法對於也要處理08/22 12:33
→ gmccntzx1: arguments 的話會比較方便,但是缺點就是一旦 wrapper08/22 12:34
→ gmccntzx1: 太多,要轉進呼叫到實際上 rpc 的 function 也需越多層08/22 12:34
→ gmccntzx1: 接續上面第一種方式,也可以不透過 frame 去抓 caller08/22 12:58
→ gmccntzx1: argument08/22 12:58
非常感謝您!
第二個方法看起來可以解決這個問題
再次感謝
※ 編輯: XperiaZ6C (111.184.77.196 臺灣), 08/22/2020 13:27:21
→ gmccntzx1: (`・∀・)b 08/22 17:27
→ azuel: 看了這些討論之後我覺得自己好菜 08/23 18:03
推 gmccntzx1: @azuel 不用這樣說,每個人都嘛是從新手開始走起。覺 08/23 20:51
→ gmccntzx1: 得自己不足的時候,就繼續努力把能力練起來,這才是該 08/23 20:51
→ gmccntzx1: 做的事。而且說實在的,我也沒有解決了什麼高深的問題 08/23 20:51
→ gmccntzx1: ,純粹只是分享以我目前所知所能構成的解法。以後對 P 08/23 20:51
→ gmccntzx1: ython 了解更透徹後,說不定又會有更好的解法。共勉之 08/23 20:51