如何解决Python |实例化之前的类方法装饰器
前言:这个问题可能比标题可能提示的问题简单
我正在尝试实现一个简单的事件处理程序系统,使用装饰器向事件“预订”各种方法和功能。
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'
显然,这里的问题是我在事件中添加了“静态”(或者是“ unbound”?)myMethod
,该事件与实例无关因此没有self
的任何实例。
诸如this之类的答案是指实现装饰器以将方法 如 包装起来,但是我使用装饰器的原因是您获得的访问权限在执行初始代码后。
一种想法是必须在MyClass.__init__()
构造函数中运行某些东西,因为只有那时才创建了一个实例,并且您可以访问self
,但是您将如何运行装饰器 仅 ?更不用说获得我们想要的结果了。
问题
为实现示例1中所示的行为,我有什么选择,但是由于runner.add()
有点冗长,丑陋,语法与示例2尽可能接近(或者可能与其他任何“干净的”变体一样),而且肯定不如装饰工精简。
干杯!
解决方法
您不必像对待函数和方法那样一视同仁地处理它们:
功能
:-
[A]
将函数正常添加到列表中
方法:
- 调用装饰器时的未绑定方法,因此尚无
self
的关联实例或值 -
[B]
通过设置其_tagged
属性,我们在未绑定的方法(在创建实例之前)“标记”该方法 -
[C]
创建实例(并填充self
变量)后,我们将在__init__()
内进行搜索并添加所有带标签的方法 - 我们可以在以后添加方法,因为一旦将它们绑定到实例,
self
参数就被填充了(这意味着它在技术上没有类似于functools.partial()
的参数)
import inspect
class Runner:
def __init__(self):
self.functions = []
def add(self,function):
if len(inspect.signature(function).parameters) == 0:
# [A] adds if has no parameters
self.functions.append(function)
else:
# [B] tags if has 1 parameter (unbound methods have "self" arg)
function._tagged = True
return function
# [C] search through object and add all tagged methods
def add_all_tagged_methods(self,object):
for method_name in dir(object):
method = getattr(object,method_name)
if hasattr(method,'_tagged'):
self.functions.append(method)
def run(self):
for function in self.functions:
function()
runner = Runner()
然后使用与下面相同的初始代码
@runner.add
def myFunction():
print('myFunction')
class MyClass:
def __init__(self):
runner.add_all_tagged_methods(self)
@runner.add
def myMethod(self):
print('myMethod')
myObject = MyClass()
myObjectMethod = myObject.myMethod
runner.run()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。