作者skyconquer (梅郭曲)
看板Python
标题Re: [问题] function物件可以透过class呼叫吗
时间Sat Aug 22 10:27:06 2020
我把原Po文章放在底下,方便对照。
试试我写的程式码, 看看有无达成你的需求。
麻烦特别注意一下注解的部份︰
******************************************************************************
def nonMemberFunc(arg):
print("nonMemberFunc is called with arg: " + str(arg))
class Logger(object):
def __getfunc__(self, func, arg):
print(func.__name__)
## 移除"func()"的括号,将传入的func变成object并
## 呼叫其 member "__name__"
print(func)
## 移除"func()"的括号,将传入的func变成object并
## 印出其资讯
return func(arg)
def method1(self, arg):
print("method1 is called with argument: "+str(arg) + "\n")
def method2(self, arg):
print("method2 is called with argument: "+str(arg) + "\n")
def method3(self, arg):
print("method3 is called with argument: "+str(arg) + "\n")
if __name__ == "__main__":
L1 = Logger()
L1.__getfunc__(L1.method1, "m1")
L1.__getfunc__(L1.method2, "m2")
L1.__getfunc__(L1.method1, "m3")
L1.__getfunc__(nonMemberFunc, "nonMemberFuncArg")
******************************************************************************
输出结果:
method1
<bound method Logger.method1 of <__main__.Logger object at 0x7f0ff113b9d0>>
method1 is called with argument: m1
method2
<bound method Logger.method2 of <__main__.Logger object at 0x7f0ff113b9d0>>
method2 is called with argument: m2
method1
<bound method Logger.method1 of <__main__.Logger object at 0x7f0ff113b9d0>>
method1 is called with argument: m3
nonMemberFunc
<function nonMemberFunc at 0x7f0ff112c1f0>
nonMemberFunc is called with arg: nonMemberFuncArg
※ 引述《XperiaZ6C (索尼)》之铭言:
: 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
: → gmccntzx1: 你的意思是,每当一个 member method 被呼叫时,就要 08/22 09:23
: → gmccntzx1: 抓到是谁被呼叫吗? 08/22 09:23
: → gmccntzx1: 如果要的效果是这样,我目前是有想到可以透过 metacla 08/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’,只要透过 logg 08/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
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 59.124.207.79 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1598063228.A.DA5.html
1F:→ gmccntzx1: 痾,这样并没有达到原 PO 要的那种呼叫方式呀 08/22 10:33
加上一个未定义在Logger class中的Non-member function "nonMemberFunc(arg)"
并呼叫其member "__name__"的实例。这样应该是有解决如何取得该函数"物件"的问题,
并且作为function运作上也没问题。不知道我哪里误解了吗?
※ 编辑: skyconquer (59.124.207.79 台湾), 08/22/2020 10:44:11
2F:→ gmccntzx1: 从他的回文来看,要的呼叫方式应该是 `logger.func()` 08/22 10:47
3F:→ gmccntzx1: 但是那个 `func` 并不在 logger 内 08/22 10:47
4F:→ gmccntzx1: 你可以看上一篇我贴的那个,不过还是等原 PO 说明吧 08/22 10:48
看到回文了,所以他是要把一个non-member function 用 member-function的方式来
呼叫?
※ 编辑: skyconquer (59.124.207.79 台湾), 08/22/2020 10:53:12
5F:→ gmccntzx1: 对,我对後来回文的理解是这样 08/22 10:54
6F:→ gmccntzx1: 只是这种做法很少见,所以我才想说等原 PO 说明他实际 08/22 10:55
7F:→ gmccntzx1: 上想做什麽功能 08/22 10:55
8F:→ gmccntzx1: 一般来说也会用类似你这种的方式或前篇 TitanEric 提到 08/22 10:56
9F:→ gmccntzx1: 的 decorator 去做,因为这样也能处理 caller argument 08/22 10:57
看来只能等说明了。
※ 编辑: skyconquer (59.124.207.79 台湾), 08/22/2020 11:11:43
10F:推 XperiaZ6C: 拍谢,我好像整个会错意了,有更新在原文 08/22 11:55