装饰一个方法

2023-12-09

在我的 Python 应用程序中,我使用事件在不同插件之间进行通信。 现在,我想我可以使用装饰器来为我做这件事,而不是手动注册事件的方法。

我想让它看起来像这样:

@events.listento('event.name')
def myClassMethod(self, event):
    ...

我首先尝试这样做:

def listento(to):
    def listen_(func):
        myEventManager.listen(to, func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        return func
    return listen_

当我打电话时myEventManger.listen('event', self.method)从实例内部来看,一切都运行良好。但是,如果我使用装饰器方法,self争论从未被通过。

在网上搜索解决方案后,我尝试过的另一种方法是使用类作为装饰器:

class listen(object):
    def __init__(self, method):
        myEventManager.listen('frontend.route.register', self)
        self._method = method
        self._name = method.__name__
        self._self = None

    def __get__(self, instance, owner):
        self._self = instance
        return self

    def __call__(self, *args, **kwargs):
        return self._method(self._self, *args, **kwargs)

这种方法的问题是我不太理解这个概念__get__,而且我不知道如何合并这些参数。 只是为了测试,我尝试使用固定事件来监听,但是使用这种方法,什么也没有发生。当我添加打印语句时,我可以看到__init__叫做。 如果我添加额外的“旧式”事件注册,两者都会__get__and__call__尽管有新的装饰器,但事件仍然有效。

实现我正在寻找的目标的最佳方法是什么,或者我只是错过了装饰器的一些重要概念?


装饰器方法不起作用,因为装饰器是在构造类时调用的,而不是在构造实例时调用的。当你说

class Foo(object):
  @some_decorator
  def bar(self, *args, **kwargs):
    # etc etc

then some_decorator当类 Foo 被构造时会被调用,并且它会被传递一个unbound方法,而不是实例的绑定方法。这就是为什么self没有通过。

另一方面,只要您只创建,第二种方法就可以工作one您使用装饰器的每个类的对象,and如果你聪明一点的话。如果你定义listen如上所述,然后定义

class Foo(object):
  def __init__(self, *args, **kwargs):
    self.some_method = self.some_method # SEE BELOW FOR EXPLANATION
    # etc etc
  @listen
  def some_method(self, *args, **kwargs):
    # etc etc

Then listen.__get__当有人试图打电话时会被呼叫f.some_method直接为一些f...但你的计划的重点是没有人这样做!事件回调机制正在调用listen直接实例,因为这就是它传递的内容listen实例正在调用它在创建时隐藏的未绑定方法。listen.__get__永远不会被叫到_self参数永远无法正确设置...unless您明确访问self.some_method你自己,就像我在__init__方法同上。然后listen.__get__将在实例创建时调用并且_self将被正确设置。

问题是(a)这是一个非常非常可怕的黑客攻击,并且(b)如果您尝试创建两个实例Foo那么第二个将覆盖_self由第一个设置,因为仍然只有一个listen正在创建的对象,并且该对象与类相关联,而不是与实例相关联。如果您只使用过一个Foo实例那么你就可以了,但是如果你必须让事件触发两个不同的Foo那么您只需使用“旧式”事件注册即可。

TL,DR版本:装饰一个方法装饰unbound类的方法,而您希望事件管理器通过bound实例的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

装饰一个方法 的相关文章

  • 尽管极其懒惰,但如何在 Python 中模拟 IMAP 服务器?

    我很好奇是否有一种简单的方法来模拟 IMAP 服务器 例如imaplib模块 在Python中 without做很多工作 是否有预先存在的解决方案 理想情况下 我可以连接到现有的 IMAP 服务器 进行转储 并让模拟服务器在真实的邮箱 电子
  • 如何在刻度标签和轴之间添加空间

    我已成功增加刻度标签的字体 但现在它们距离轴太近了 我想在刻度标签和轴之间添加一点呼吸空间 如果您不想全局更改间距 通过编辑 rcParams 并且想要更简洁的方法 请尝试以下操作 ax tick params axis both whic
  • 如何生成给定范围内的回文数列表?

    假设范围是 1 X 120 这是我尝试过的 gt gt gt def isPalindrome s check if a number is a Palindrome s str s return s s 1 gt gt gt def ge
  • 更改自动插入 tkinter 小部件的文本颜色

    我有一个文本框小部件 其中插入了三条消息 一条是开始消息 一条是结束消息 一条是在 单位 被摧毁时发出警报的消息 我希望开始和结束消息是黑色的 但被毁坏的消息 参见我在代码中评论的位置 插入小部件时颜色为红色 我不太确定如何去做这件事 我看
  • Python 多处理示例不起作用

    我正在尝试学习如何使用multiprocessing但我无法让它发挥作用 这是代码文档 http docs python org 2 library multiprocessing html from multiprocessing imp
  • __del__ 真的是析构函数吗?

    我主要用 C 做事情 其中 析构函数方法实际上是为了销毁所获取的资源 最近我开始使用python 这真的很有趣而且很棒 我开始了解到它有像java一样的GC 因此 没有过分强调对象所有权 构造和销毁 据我所知 init 方法对我来说在 py
  • 从列表中的数据框列中搜索部分字符串匹配 - Pandas - Python

    我有一个清单 things A1 B2 C3 我有一个 pandas 数据框 其中有一列包含用分号分隔的值 某些行将包含与上面列表中的一项的匹配 它不会是完美的匹配 因为它在其中包含字符串的其他部分 该列 例如 该列中的一行可能有 哇 这里
  • Python 中的二进制缓冲区

    在Python中你可以使用StringIO https docs python org library struct html用于字符数据的类似文件的缓冲区 内存映射文件 https docs python org library mmap
  • 在pyyaml中表示具有相同基类的不同类的实例

    我有一些单元测试集 希望将每个测试运行的结果存储为 YAML 文件以供进一步分析 YAML 格式的转储数据在几个方面满足我的需求 但测试属于不同的套装 结果有不同的父类 这是我所拥有的示例 gt gt gt rz shorthand for
  • HTTPS 代理不适用于 Python 的 requests 模块

    我对 Python 还很陌生 我一直在使用他们的 requests 模块作为 PHP 的 cURL 库的替代品 我的代码如下 import requests import json import os import urllib impor
  • 如何将 numpy.matrix 提高到非整数幂?

    The 运算符为numpy matrix不支持非整数幂 gt gt gt m matrix 1 0 0 5 0 5 gt gt gt m 2 5 TypeError exponent must be an integer 我想要的是 oct
  • Numpy 优化

    我有一个根据条件分配值的函数 我的数据集大小通常在 30 50k 范围内 我不确定这是否是使用 numpy 的正确方法 但是当数字超过 5k 时 它会变得非常慢 有没有更好的方法让它更快 import numpy as np N 5000
  • Nuitka 未使用 nuitka --recurse-all hello.py [错误] 编译 exe

    我正在尝试通过 nuitka 创建一个简单的 exe 这样我就可以在我的笔记本电脑上运行它 而无需安装 Python 我在 Windows 10 上并使用 Anaconda Python 3 我输入 nuitka recurse all h
  • 为美国东部以外地区的 Cloudwatch 警报发送短信?

    AWS 似乎没有为美国东部以外的 SNS 主题订阅者提供 SMS 作为协议 我想连接我的 CloudWatch 警报并在发生故障时接收短信 但无法将其发送到 SMS YES 经过一番挖掘后 我能够让它发挥作用 它比仅仅选择一个主题或输入闹钟
  • 检查所有值是否作为字典中的键存在

    我有一个值列表和一本字典 我想确保列表中的每个值都作为字典中的键存在 目前我正在使用两组来确定字典中是否存在任何值 unmapped set foo set bar keys 有没有更Pythonic的方法来测试这个 感觉有点像黑客 您的方
  • 如何从没有结尾的管道中读取 python 中的 stdin

    当管道来自 打开 时 不知道正确的名称 我无法从 python 中的标准输入或管道读取数据 文件 我有作为例子管道测试 py import sys import time k 0 try for line in sys stdin k k
  • 用于运行可执行文件的python多线程进程

    我正在尝试将一个在 Windows 上运行可执行文件并管理文本输出文件的 python 脚本升级到使用多线程进程的版本 以便我可以利用多个核心 我有四个独立版本的可执行文件 每个线程都知道要访问它们 这部分工作正常 我遇到问题的地方是当它们
  • 对输入求 Keras 模型的导数返回全零

    所以我有一个 Keras 模型 我想将模型的梯度应用于其输入 这就是我所做的 import tensorflow as tf from keras models import Sequential from keras layers imp
  • Spark.read 在 Databricks 中给出 KrbException

    我正在尝试从 databricks 笔记本连接到 SQL 数据库 以下是我的代码 jdbcDF spark read format com microsoft sqlserver jdbc spark option url jdbc sql
  • Python 分析:“‘select.poll’对象的‘poll’方法”是什么?

    我已经使用 python 分析了我的 python 代码cProfile模块并得到以下结果 ncalls tottime percall cumtime percall filename lineno function 13937860 9

随机推荐

  • 选择相似的句子

    如果我有一组句子并且我想提取重复项 我应该像下面的示例一样工作 sentences lt c So there I was at the mercy of three monstrous trolls Today is my One Hun
  • 如何使用httpwebrequest将图像从网站拉取到本地文件

    我正在尝试使用本地 c 应用程序将网站上的一些图像提取到本地计算机上的文件中 我正在使用下面列出的代码 我尝试过 ASCII 编码和 UTF8 编码 但最终文件不正确 有人看到我做错了什么吗 当我将地址输入浏览器时 该网址有效且正确 并且可
  • 如何在net core web api中接受dd-MM-yyyy格式的日期?

    我在我的 Web API 项目中使用 net core 3 1 我创建了一个 API 它接受用户的日期 默认情况下月 日 年格式在项目中被接受 但我想接受日期日 月 年相应地格式化并验证所有日期 下面是我的API HttpGet publi
  • 标签替换非 html 链接

    我有一段代码 它将采用如下所示的文本块 示例文本 示例文本http www google com示例文本 使用preg replace callback方法和以下正则表达式 preg replace callback http w crea
  • 对 asp 中的参数化 SQL 语句进行故障排除

    我正在尝试保护一些用我猜是 VB 或 asp 编写的遗留代码 不太确定是否有区别 当我尝试执行该语句时 页面出现内部服务器错误 我确信这是连接的结果 但我不太了解该语言 不知道如何解决它 我对该语言和 ADODB 库的了解来自 W3Scho
  • 如何检查 awk 数组是否为空

    我是 AWK 的新手 试图确定我的数组是否为空 以便如果是的话我可以打印一条消息 通常我习惯于长度函数并且可以这样检查 但 AWK 似乎没有这些 这是我的工作代码 如果解析所有数据后数组中没有任何内容 我只想打印出不同的消息 add to
  • r stat_contour 多边形填充不正确

    当我使用stat contour对于多边形 某些区域不应该被填充 因为那里没有数据 我在图中标记了它们 有谁知道如何避免这种情况 另外 坐标轴和绘图区域之间有空间 如何去掉 这是绘图代码 plot contour lt function d
  • JavaScript 错误:未捕获类型错误:foo 不是函数

    由于某种原因 JavaScript 似乎无法识别我的函数 我在一些 HTML 中有一个按钮
  • 扩展 Material UI 主题中的排版

    是否可以在 Material UI 主题中定义额外的字体 字体系列 我想要得到这样的东西 export const theme createMuiTheme typography fontFamily Open Sans sans seri
  • iPhone SDK,如何获取周五20:00的NSDate对象?

    有谁知道如何获取下周五 20 00 的 NSDate 吗 Yes 本文教你如何获取当前周的星期日 我很快将其调整为周五 20 00 假设采用公历 NSDate today NSDate alloc init NSCalendar grego
  • 在使用 CefSharp 加载远程 JavaScript 时修改它们?

    我正在构建一个自定义浏览器作为远程网站界面的一部分 他们的 GUI 很糟糕 所以我做了一些 JavaScript 修改来让它看起来更好 目前 为了修改其 UI 我使用以下 GreaseMonkey 脚本 在 Firefox 上 UserSc
  • Python 中的吉他弦代码? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我对 Python 很陌生 但对编写可以模拟吉他弦的代码非常感兴趣 我该怎么做呢 或者至少我该如何开始这样做 任何帮助表示赞赏 谢谢你 EDIT 我想看看演奏不同的琴弦 音符等时
  • 使用 D3 的 Geojson 地图仅渲染要素集合中的单个路径

    我正在尝试绘制哥伦比亚某些地区的 geojson 地图 目前它只显示一条路径 我的特征集有 52 个特征 但我只能绘制这一个特征 我不知道我做错了什么 我的代码基于其他教程 我怎样才能显示所有路径 var features mapData
  • 查找字符串中的多个 url。

    resource THIS IS ABOUT WWW JONAKCOMPUTERS COM HTTP HIGHLOW COM AND TESTINGSERVER1 COM 我想将三个网址提取到另一个类似于以下内容的字符串中 all urls
  • 使用 HTML5 Canvas - 围绕任意点旋转图像

    将表盘旋转到半圆形 北半球 图像作为背景 范围可以是 0 180 度 在输入到进行画布转换的方法时 转盘将旋转并停在匹配的值上 这是我根据传递的帮助和示例尝试的phrogz 一般来说 您想要做的是 将上下文转换为画布上对象应围绕其旋转的点
  • 客户端未处理 .NET Remoting 异常

    我检查了其余的远程处理问题 这个具体案例似乎没有得到解决 我设置了 NET Remoting 服务器 客户端 在服务器端 我有一个带有可以引发异常的方法的对象 以及一个将尝试调用该方法的客户端 Server public bool MyEq
  • PHPMailer SMTP 连接失败

    我正在尝试通过 Mandrill 发送电子邮件PHP邮件程序但没有成功 在本地主机上测试 有人能告诉我问题出在哪里吗 这是来自 PHPMailer 的详细信息 2014 04 27 17 51 06 SERVER gt CLIENT 220
  • 访问pom中定义的maven属性

    如何访问普通 Maven 项目和 Maven 插件项目中 pom 中定义的 Maven 属性 Use the 属性 maven 插件编写具体的pomproperties在编译时写入文件 然后在运行时读取该文件 In your pom xml
  • ASP.NET CORE 中的流代理直播流

    我的网络摄像头有一个流 url 它返回 multipart x mixed replace boundary myboundary 的内容类型 假设可以通过以下方式访问它 http mywebcam livrestream cgi 我想在
  • 装饰一个方法

    在我的 Python 应用程序中 我使用事件在不同插件之间进行通信 现在 我想我可以使用装饰器来为我做这件事 而不是手动注册事件的方法 我想让它看起来像这样 events listento event name def myClassMet