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/cn.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灯, 水草

请输入看板名称,例如:Soft_Job站内搜寻

TOP