作为我自己的练习,我试图在Python中编写一个与C#中的事件类似的类。
以下是类中的两个主要函数(__subs是一个列表):
class Event (object):
def __iadd__ (self, other):
if not callable(other):
raise ValueError("%s must be callable" % other)
self.__subs.append(other)
return self
def __add__ (self, other):
if not callable(other):
raise ValueError("%s must be callable" % other)
new = Event()
new.__subs = [f for f in self.__subs]
new.__subs.append(other)
return new
def __call__ (self, *args, **kwargs):
for func in self.__subs:
func(*args, **kwargs)
这允许以下语法:
e1 = Event()
e1 += afunction
e2 += another
e1 (arg1, arg = val) # afunction and another will be called with arg1 and val
e2 = Event() + afunction + another
e2 (arg1, arg = val)
(Event() + afunction + another) (arg1, arg = val)
但是,我想简化最后两个就是这样的
e = afunction + another
e (arg1, arg = val)
(afunction + another) (arg1, arg = val)
我尝试过这样做,但是我收到了错误" TypeError:' function'不是可接受的基本类型"
class function (FunctionType):
def __add__ (self, other):
return Event() + self + other
我正在尝试做什么?
答案 0 :(得分:2)
你不能直接将函数子类化,没有。最多可以创建一个包装类,它将所有属性访问传递给底层函数。
要支持调用,请为包装类指定object.__call__
method:
class FunctionWrapper(object):
def __init__(self, func):
self._func = func
def __getattr__(self, attr):
return getattr(self._func, attr)
def __call__(self, *args, **kwargs):
return self._func(*args, **kwargs)
# additional methods
你可以画画'使用装饰器语法进行函数声明甚至:
@FunctionWrapper
def foo(): pass
演示:
>>> @FunctionWrapper
... def foo():
... return 'bar'
...
>>> foo
<__main__.FunctionWrapper object at 0x102544850>
>>> foo()
'bar'
>>> foo.__name__
'foo'
>>> foo.__code__
<code object foo at 0x1026cb730, file "<stdin>", line 1>