在抽象方法上实现“after”装饰器

2024-03-26

我正在尝试编写一个抽象基类A它将有一个抽象方法run用户/开发人员预计会超载。我想强制执行一些“之后”行为自动应用于派生类B,这样之后B.run()运行完毕后,将调用另一个标准方法(在数据管道中,这可以例如提交或回滚事务)。有办法实现这一点吗?

我失败的天真的尝试是:

def do_the_other_thing(func): 
    def wrapper(): 
        func() 
        print('doing the other thing!')
    return wrapper 

class A: 
    @do_the_other_thing 
    def run(self): 
        pass     

class B(A): 
    def run(self): 
        print('running!') 

B().run() 
>>> 'running!' 
>>> #'doing the other thing!'     # <--- is there a way to get this?

我当然可以通过创建不同的抽象方法来实现解决方法(例如_run) 从非抽象方法调用A.run,但这不太优雅。

早在 2007 年我就能看到这一点PEP 3124 https://www.python.org/dev/peps/pep-3124/#before-and-after-methods确切地指定了此功能,但我找不到任何对它的现代参考。


如果您不期望单独使用函数装饰器,实际上您无法完成您想要的事情用户来装饰run他们自己。您可以使用类装饰器,__init_subclass__ https://www.python.org/dev/peps/pep-0487/, or metaclasses https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/.


有了类装饰器,

class A:
    def run(self):
        pass

def do_the_other_thing(func):
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        print('doing the other thing!')
    return wrapper


def pipeline_thing(cls):
    cls.run = do_the_other_thing(cls.run)
    # do some other work
    return cls


@pipeline_thing
class B(A):

    def run(self):
        print("running!")

Or with __init_subclass__

class A:
    def run(self):
        pass

    def __init_subclass__(cls):
        super().__init_subclass__()
        cls.run = do_the_other_thing(cls.run)
        # do some other work

class B(A):

    def run(self):
         print("running!")

Or with metaclasses

class AMeta(type):

    def __init__(cls, name, bases, attrs, **kwargs):
        super().__init__(name, bases, attrs)
        cls.run = do_the_other_thing(cls.run)
        # do some other work

class A(metaclass=AMeta):
    def run(self):
        pass

class B(A):

    def run(self):
        print("running!")

这个例子对于元类来说太过分了(你正在使用metaclass.__init__- 元类中最不强大的魔法方法,你的行为可以用__init_subclass__(这是的预期用途__init_subclass__ https://www.python.org/dev/peps/pep-0487/)。以这种方式使用元类将阻止您的用户使用元类,并且会使您的代码不必要地复杂化。如果您需要管道发挥更多作用,则可以使用它们(例如,如果您需要访问__new__).

我要么使用__init_subclass__或类装饰器(@pipe或其他东西)大概也混合了B with A. As, alkasm https://stackoverflow.com/users/5087436/alkasm提到的,你可以使A继承自abc.ABC并装饰run with abc.abstractmethod确保子类实现它。

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

在抽象方法上实现“after”装饰器 的相关文章

  • Python正则表达式替换除特定单词之外的所有内容

    我正在尝试执行以下操作用正则表达式 import re x re compile going you words to replace s I am going home now thank you string to modify pri
  • Python argparse 作为函数

    以这种方式获取命令行参数有什么本质上的错误吗 我的意思是把参数解析放入它自己的函数中 它会被认为是非 Pythonic 或更严重吗 usr bin python import argparse def getArgs argv None p
  • 使用 JPype - 如何访问 JDBC 元数据函数

    我在用着杰 德贝API https launchpad net jaydebeapi它使用 JPype 加载 FileMaker 的 JDBC 驱动程序并提取数据 但我也希望能够获取所有表的列表在数据库中 In the JDBC 文档 ht
  • 扭曲多种协议

    我希望为我正在从事的项目学习扭曲 该项目需要服务器响应 HTTP 请求以及通过 TCP 连接的其他协议 Twisted能够同时处理多种协议吗 我想使用 Twisted Web 来帮助处理 HTTP 但同时需要响应其他端口上的 TCP 连接
  • 如何将数据从 JavaScript 发送到 Python

    我正在 jinja2 和 python2 7 上使用 GAE 进行 Web 开发 我可以从Python获取数据 但我无法将数据从 JavaScript 发送到 Python 这是 JavaScript 代码 function toSave
  • NLTK:包错误?朋克和泡菜?

    基本上 我不知道为什么会收到此错误 只是为了获得更多图像 这里有一个代码格式的类似消息 由于是最新的 该帖子的答案已经在消息中提到 Preprocessing raw texts LookupError Traceback most rec
  • 如何使用格式保存 Tkinter 文本小部件的内容

    我在 python 中使用 Tkinter 在文本窗口中显示输出 我发现使用 get 功能我可以从此窗口检索文本内容 但我有用不同背景颜色标记的文本部分 是否可以将内容与这些颜色一起复制到文件 例如 html 或 doc 中 没有对你想要的
  • Python 中 eval("input()") 和 eval(input()) 之间的区别

    我正在尝试以下功能 x eval input 输入为 123 x 的类型也是int 它工作正常 In 22 x eval input enter enter 123 In 24 print type x
  • 统计Sweep算子的Python实现

    我正在学习一些用书中缺失的数据进行统计的技术 缺失数据的统计分析作者 利特尔和鲁宾 对于处理单调无响应数据来说 一个特别有用的函数是扫频操作员 详情见第 148 151 页 我知道 R 模块gmm有swp函数可以做到这一点 但我想知道是否有
  • 如何在 Django 中像应用程序一样从配置中注册 Flask 蓝图?

    如何从我的配置中注册 Flask 蓝图 就像 Django 中的应用程序一样 我想在配置文件中定义蓝图 它将自动注册 config py BLUEPRINTS news files 实际上我一直在一个暂定名为的项目中勾勒出类似的东西臀部口袋
  • 将具有多个时区的 pandas 列转换为单个时区

    Problem 我在 pandas DataFrame 中有一个列 其中包含带有时区的时间戳 此列中有两个不同的时区 我需要确保只有一个 这是该列末尾的输出 260003 2019 05 21 12 00 00 06 00 260004 2
  • 如何检查discord.py中的所有者

    我试图让这个命令只有所有者才能运行它 是否有办法检查服务器的最高角色或创建者 我尝试了 commands is owner 但这仅检查某人是否是机器人的所有者 Guild owner https discordpy readthedocs
  • 在 Python 中通过网络发送对象的最佳方式是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我需要通过网络发送对象 我将使用 Twisted 并且我刚刚开始查看它的文档 据我所知 python实现套接字的唯一方式是通过文本 那么我如何使
  • Scrapy FakeUserAgentError:获取浏览器时发生错误

    我使用 Scrapy FakeUserAgent 并在我的 Linux 服务器上不断收到此错误 Traceback most recent call last File usr local lib64 python2 7 site pack
  • Python-使用元组作为列表索引[重复]

    这个问题在这里已经有答案了 我有一个元组列表 tuples list 1 0 2 3 3 2 2 0 我想访问二维数组的元素a例如 使用其中一些元组 for i in range 3 print a tuples list i 应该输出的值
  • Tensorflow `tf.layers.batch_normalization` 不会向 `tf.GraphKeys.UPDATE_OPS` 添加更新操作

    以下代码 复制 粘贴可运行 说明了如何使用tf layers batch normalization import tensorflow as tf bn tf layers batch normalization tf constant
  • 使用 Python 获取 Youtube 数据

    我正在尝试学习如何分析网络上可用的社交媒体数据 我从 Youtube 开始 from apiclient errors import HttpError from outh2client tools import argparser fro
  • 如何将 Django 数据库中的模板标签解释/渲染为 HTML

    我正在尝试添加带有来自 Django 管理站点的图像的帖子 但安全 自动转义关闭过滤器无法解释 Django 的模板标签 My input and page look like 复制图像地址 给出http 127 0 0 1 8000 7B
  • Pandas 数据框可对多列和要列出的值进行字典

    我有一个数据框 id key a1 1 a2 1 a3 1 a4 2 a5 2 a6 3 我想创建一本字典key作为机器号 并且id列作为列表 like 1 a1 a2 a3 2 a4 a5 3 a6 我可以先使用 groupby 然后再使
  • 类unix系统中的python和python3命令有什么区别?

    我通读了每个命令的描述 但每个命令的描述都是完全相同的 所以我不明白这两个命令在类 Unix 系统中的工作方式有何不同 谁能解释其中的区别吗 Python3命令的引入是因为python命令指向了python2 从那时起 Python3 已成

随机推荐

  • 如何使用rest api将数据集作为csv文件导入到power bi?

    我想在 power bi 中自动执行导入过程 但我找不到如何将 csv 文件发布为数据集 我正在为此使用 C 解决方案 有没有办法做到这一点 您无法将 CSV 文件直接导入到 Power BI 服务中已发布的数据集 AddRowsAPIEn
  • 如果时区设置为“UTC”,SimpleDateFormat 会忽略“XXX”

    我正在尝试按以下格式将当前日期时间输出为 UTC 2016 01 11T14 08 42 00 00 final SimpleDateFormat formatter new SimpleDateFormat yyyy MM dd T HH
  • PHP 的项目结构

    我是 PHP 新手 想了解 php 项目的目录结构 我有Java方面的经验 在java中我们有src包含java源文件 WEB INF包含lib和jsp页面 PHP 中有类似的标准目录结构吗 我们在 php 中也有分层吗 就像我们在 jav
  • Python 现在或将来会弃用“pytz”吗?

    pytz https pytz sourceforge net 用于Django 版本 选择当前时区 https docs djangoproject com en 3 2 topics i18n timezones selecting t
  • MYSQL 使用空间索引

    我正在尝试利用空间索引 我有一个 ip 表和一个包含 ip 块范围的 ip2geo 表 我正在尝试将 Geo ID 分配给 ip2geo 表中的每个 ip 当尝试使用列值进行选择时 空间索引不会被使用 EXPLAIN SELECT SELE
  • 为什么通过 AJAX 发送此 POST 变量为 Null? (jquery/php)

    该 JavaScript 用于 加载更多 功能 当单击按钮 moreg 时 它会从 load php 中获取固定数量的元素 function moreg click load var countg 1 load function load
  • 为什么我的 Nginx 反向代理执行 301 重定向而不是代理?

    我在 docker 容器内有一个 Nginx 反向代理 它监听端口 3000 并暴露给 3002 docker run p 3002 3000 这个想法是这个反向代理将代理 my app到我的笔记本电脑中在端口 8080 上运行的实例 和
  • 以编程方式更改视图的右边距?

    这个属性可以在Java代码中动态改变吗 android layout marginRight 我有一个TextView 它必须动态地将其位置向左更改一些像素 如何以编程方式做到这一点 编辑 一种更通用的方法 不依赖于布局类型 除了它是支持边
  • 如何在 IndexedDB 中进行 JOIN 类型查询

    我尝试按照以下教程进行操作http hacks mozilla org 2010 06 comparing indexeddb and webdatabase http hacks mozilla org 2010 06 comparing
  • 如何在 jquery 表单验证上显示独特的成功消息

    希望你能在这方面帮助我 我目前正在使用这个 jQuery 插件 验证 主页 http bassistance de jquery plugins jquery plugin validation 我一直在这里阅读相关问题 但这是最接近的 h
  • 我可以用什么来替换 HTML 中的   ?

    nbsp nbsp 我觉得很丑 边距和 或填充 CSS 属性 如下所示 p style padding left 10px Hello p 值得注意的是 放置这样的内联样式通常被认为是不好的做法 您通常在外部 css 文件中声明一个选择器并
  • 服务器场(服务计划)SKU

    是否有文档列出了 Azure 应用服务计划 服务器场 支持的 sku 名称和层 例如 名称 S1 等级 标准 S1 标准 和 名称 Y1 层 动态 功能消耗计划 支持的值列表 是否有第二年的消费计划 和服务器配置确实有助于规划 有多种方法可
  • Rails 4 中“确认”条件的干净方法

    我的 Rails4 页面上有一个使用 slim 语法的 link to 以下链接 to link to exports path data confirm Are you sure 现在需要仅在特定条件下显示确认消息 我们如何在rails4
  • 如何删除数据框中值的顺序不重要的行

    我有一个像这样的数据框 source target weight 1 2 5 2 1 5 1 2 5 1 2 7 3 1 6 1 1 6 1 3 6 我的目标是删除重复的行 但源列和目标列的顺序并不重要 事实上 两列的顺序并不重要 应该将其
  • 使用 Linq to SQL 删除表中的行

    我有一个体育数据库 其中有一个表 groupmembers 其中包含字段 ID groupID 和 memberID 我从名为 txtRemoveGroupMember 的文本框中获取memberID 并从复选框列表中获取groupID 现
  • 使用 Boost Spirit 解析语法

    我正在尝试解析像下面这样的树表达式之类的 C 函数 使用精神解析器框架 http en wikipedia org wiki Spirit Parser Framework F A B GREAT SOME NOT C YES 为此 我尝试
  • 如何在作为协议类型的 Swift 通用数据结构中使用弱引用?

    我想在通用数据结构中使用弱引用 在里面 下面是数组的示例 但通常是任何泛型类型 我几乎可以得到它 上班 我的实验开始得很顺利 以下作品 Array of weak references OK struct WeakReference
  • 更改 ListView 阴影颜色和大小

    当 ListView 中的项目列表比 ListView 的大小长时 您会看到一个阴影 指示上方或下方有更多项目 默认情况下 该阴影是黑色的 这是不可取的 如果我将 cacheColorHint 设置为以下内容 android cacheCo
  • 调用布尔值的成员函数 fetchAll()

    我有以下问题 这个错误一直伴随着我 致命错误 未捕获错误 在 C xampp htdocs certificado functions php 49 中的布尔值上调用成员函数 fetchAll 堆栈跟踪 0 C xampp htdocs c
  • 在抽象方法上实现“after”装饰器

    我正在尝试编写一个抽象基类A它将有一个抽象方法run用户 开发人员预计会超载 我想强制执行一些 之后 行为自动应用于派生类B 这样之后B run 运行完毕后 将调用另一个标准方法 在数据管道中 这可以例如提交或回滚事务 有办法实现这一点吗