前言:这个问题可能比标题所暗示的要简单
我正在尝试实现一个简单的事件处理程序系统,使用装饰器将各种方法和函数“订阅”到一个事件。
1. 事件处理程序的简单方法
一种简单的方法是创建一个类来添加和运行事件:
# class for adding and running functions, aka an event handler
class Runner:
def __init__(self):
self.functions = []
def add(self, function):
self.functions.append(function)
def run(self):
for function in self.functions:
function()
runner = Runner()
然后添加各种功能或方法:
# random example function
def myFunction():
print('myFunction')
# random example class
class MyClass:
def myMethod(self):
print('myMethod')
# getting instance of class & method
myObject = MyClass()
myObjectMethod = myObject.myMethod
runner.add(myFunction)
runner.add(myObjectMethod)
runner.run()
这导致:
> py main.py
myFunction
myMethod
好的!它按预期工作
2.装饰器方法
所以这没关系,但我最近了解了装饰器,并认为我可以通过替换有点丑陋的runner.add()方法来整理语法。
首先,我将Runner.add()方法更改为装饰器:
class Runner:
def __init__(self):
self.functions = []
def add(self, function):
self.functions.append(function)
return function # <-- returns function
def run(self):
for function in self.functions:
function()
runner = Runner()
然后我删除runner.add()调用并插入装饰器:
@runner.add
def myFunction():
print('myFunction')
class MyClass:
@runner.add
def myMethod(self):
print('myMethod')
# myObject = MyClass()
# myObjectMethod = myObject.myMethod
runner.run()
这显然会导致:
> py main.py
myFunction
Traceback (most recent call last):
...
TypeError: myMethod() missing 1 required positional argument: 'self'
显然,这里的问题是我将“静态”(或者它是“未绑定”?)添加myMethod到事件中,该事件与实例无关,因此没有任何实例self。
诸如此类的答案指的是实现装饰器以在调用时包装方法,但是我使用装饰器的原因是您在初始代码执行时获得的访问权限。
一个想法是必须在MyClass.__init__()构造函数中运行一些东西,因为只有这样才能创建一个实例并且您可以访问self,但是那么如何仅在实例化时运行装饰器呢?更不用说实现我们在这里追求的结果了。
问题
我有什么选择来实现示例 1 中所示的行为,但语法尽可能接近示例 2(或任何其他“看起来干净”的变体),因为它有点冗长、丑陋,而且肯定不像装饰器那样精简runner.add()。
慕桂英4014372
相关分类