如何从 Python 3.x 中的类定义将参数传递给元类?

2024-04-06

这是 Python 3.x 版本如何从类定义将参数传递给元类? https://stackoverflow.com/questions/13762231/how-to-pass-arguments-to-the-metaclass-from-the-class-definition问题,根据请求单独列出,因为答案与 Python 2.x 显着不同。


在 Python 3.x 中,如何将参数传递给元类__prepare__, __new__, and __init__函数以便类作者可以向元类提供有关如何创建类的输入?

作为我的用例,我使用元类来启用类的自动注册及其子类到 PyYAML 中用于加载/保存 YAML 文件。这涉及一些 PyYAML 库存中不可用的额外运行时逻辑YAMLObjectMetaClass。此外,我希望允许类作者选择指定 PyYAML 用于表示类和/或用于构造和表示的函数对象的标签/标签格式模板。我已经发现我不能使用 PyYAML 的子类YAMLObjectMetaClass为了完成这个——“因为我们无法访问实际的类对象__new__”根据我的代码注释——所以我正在编写自己的元类来包装 PyYAML 的注册函数。

最终,我想做一些类似的事情:

from myutil import MyYAMLObjectMetaClass

class MyClass(metaclass=MyYAMLObjectMetaClass):
    __metaclassArgs__ = ()
    __metaclassKargs__ = {"tag": "!MyClass"}

...在哪里__metaclassArgs__ and __metaclassKargs__将是争论__prepare__, __new__, and __init__的方法MyYAMLObjectMetaClass当。。。的时候MyClass正在创建类对象。

当然,我可以使用中列出的“保留属性名称”方法这个问题的Python 2.x版本 https://stackoverflow.com/questions/13762231/how-to-pass-arguments-to-the-metaclass-from-the-class-definition,但我知道有一种更优雅的方法可用。


在深入研究 Python 的官方文档后,我发现 Python 3.x 提供了一种将参数传递给元类的本机方法,尽管它并非没有缺陷。

只需将其他关键字参数添加到类声明中即可:

class C(metaclass=MyMetaClass, myArg1=1, myArg2=2):
  pass

...它们会像这样传递到您的元类中:

class MyMetaClass(type):

  @classmethod
  def __prepare__(metacls, name, bases, **kargs):
    #kargs = {"myArg1": 1, "myArg2": 2}
    return super().__prepare__(name, bases, **kargs)

  def __new__(metacls, name, bases, namespace, **kargs):
    #kargs = {"myArg1": 1, "myArg2": 2}
    return super().__new__(metacls, name, bases, namespace)
    #DO NOT send "**kargs" to "type.__new__".  It won't catch them and
    #you'll get a "TypeError: type() takes 1 or 3 arguments" exception.

  def __init__(cls, name, bases, namespace, myArg1=7, **kargs):
    #myArg1 = 1  #Included as an example of capturing metaclass args as positional args.
    #kargs = {"myArg2": 2}
    super().__init__(name, bases, namespace)
    #DO NOT send "**kargs" to "type.__init__" in Python 3.5 and older.  You'll get a
    #"TypeError: type.__init__() takes no keyword arguments" exception.

你必须离开kargs通话中type.__new__ and type.__init__(Python 3.5 及更早版本;请参阅下面的“更新”)或者会给你一个TypeError由于传递太多参数而引发异常。这意味着,当以这种方式传递元类参数时,我们总是必须实现MyMetaClass.__new__ and MyMetaClass.__init__防止我们的自定义关键字参数到达基类type.__new__ and type.__init__方法。type.__prepare__似乎可以优雅地处理额外的关键字参数(这就是为什么我在示例中传递它们,以防万一有一些我不知道的功能依赖于**kargs),所以定义type.__prepare__是可选的。

UPDATE

在Python 3.6中,出现了type被调整并且type.__init__现在可以优雅地处理额外的关键字参数。您仍然需要定义type.__new__(抛出TypeError: __init_subclass__() takes no keyword arguments例外)。

分解

在 Python 3 中,您可以通过关键字参数而不是类属性指定元类:

class MyClass(metaclass=MyMetaClass):
  pass

这句话大致翻译为:

MyClass = metaclass(name, bases, **kargs)

...在哪里metaclass是您传入的“元类”参数的值,name是你的班级的字符串名称('MyClass'), bases是您传入的任何基类(零长度元组()在这种情况下),并且kargs是任何未捕获的关键字参数(空的dict {}在这种情况下)。

进一步细分,该声明大致可翻译为:

namespace = metaclass.__prepare__(name, bases, **kargs)  #`metaclass` passed implicitly since it's a class method.
MyClass = metaclass.__new__(metaclass, name, bases, namespace, **kargs)
metaclass.__init__(MyClass, name, bases, namespace, **kargs)

...在哪里kargs始终是dict我们传递给类定义的未捕获的关键字参数。

分解我上面给出的例子:

class C(metaclass=MyMetaClass, myArg1=1, myArg2=2):
  pass

...大致翻译为:

namespace = MyMetaClass.__prepare__('C', (), myArg1=1, myArg2=2)
#namespace={'__module__': '__main__', '__qualname__': 'C'}
C = MyMetaClass.__new__(MyMetaClass, 'C', (), namespace, myArg1=1, myArg2=2)
MyMetaClass.__init__(C, 'C', (), namespace, myArg1=1, myArg2=2)

这些信息大部分来自Python 关于“自定义类创建”的文档 https://docs.python.org/3.3/reference/datamodel.html#customizing-class-creation.

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

如何从 Python 3.x 中的类定义将参数传递给元类? 的相关文章

  • 使用特定的类/函数预加载 Jupyter Notebook

    我想预加载一个笔记本 其中包含我在另一个文件中定义的特定类 函数 更具体地说 我想用 python 来做到这一点 比如加载一个配置文件 包含所有相关的类 函数 目前 我正在使用 python 生成笔记本并在服务器上自动启动它们 因为不同的
  • 元组有什么用?

    我现在正在学习 Python 课程 我们刚刚介绍了元组作为数据类型之一 我阅读了它的维基百科页面 但是 我无法弄清楚这种数据类型在实践中会有什么用处 我可以提供一些需要一组不可变数字的示例吗 也许是在 Python 中 这与列表有何不同 每
  • 如何使用 opencv.omnidir 模块对鱼眼图像进行去扭曲

    我正在尝试使用全向模块 http docs opencv org trunk db dd2 namespacecv 1 1omnidir html用于对鱼眼图像进行扭曲处理Python 我正在尝试适应这一点C 教程 http docs op
  • Python 中的舍入浮点问题

    我遇到了 np round np around 的问题 它没有正确舍入 我无法包含代码 因为当我手动设置值 而不是使用我的数据 时 返回有效 但这是输出 In 177 a Out 177 0 0099999998 In 178 np rou
  • 处理 Python 行为测试框架中的异常

    我一直在考虑从鼻子转向行为测试 摩卡 柴等已经宠坏了我 到目前为止一切都很好 但除了以下之外 我似乎无法找出任何测试异常的方法 then It throws a KeyError exception def step impl contex
  • 使用 Python 从文本中删除非英语单词

    我正在 python 上进行数据清理练习 我正在清理的文本包含我想删除的意大利语单词 我一直在网上搜索是否可以使用像 nltk 这样的工具包在 Python 上执行此操作 例如给出一些文本 Io andiamo to the beach w
  • 跟踪 pypi 依赖项 - 谁在使用我的包

    无论如何 是否可以通过 pip 或 PyPi 来识别哪些项目 在 Pypi 上发布 可能正在使用我的包 也在 PyPi 上发布 我想确定每个包的用户群以及可能尝试积极与他们互动 预先感谢您的任何答案 即使我想做的事情是不可能的 这实际上是不
  • 使用 kivy textinput 的 'input_type' 属性的问题

    您好 我在使用 kivy 的文本输入小部件的 input type 属性时遇到问题 问题是我制作了两个自定义文本输入 其中一个称为 StrText 其中设置了 input type text 然后是第二个文本输入 名为 NumText 其
  • Python zmq SUB 套接字未接收 MQL5 Zmq PUB 套接字

    我正在尝试在 MQL5 中设置一个 PUB 套接字 并在 Python 中设置一个 SUB 套接字来接收消息 我在 MQL5 中有这个 include
  • 在Python中连接反斜杠

    我是 python 新手 所以如果这听起来很简单 请原谅我 我想加入一些变量来生成一条路径 像这样 AAAABBBBCCCC 2 2014 04 2014 04 01 csv Id TypeOfMachine year month year
  • datetime.datetime.now() 返回旧值

    我正在通过匹配日期查找 python 中的数据存储条目 我想要的是每天选择 今天 的条目 但由于某种原因 当我将代码上传到 gae 服务器时 它只能工作一天 第二天它仍然返回相同的值 例如当我上传代码并在 07 01 2014 执行它时 它
  • Python beautifulsoup 仅限 1 级文本

    我看过其他 beautifulsoup 得到相同级别类型的问题 看来我的有点不同 这是网站 我正试图拿到右边那张桌子 请注意表的第一行如何展开为该数据的详细细分 我不想要那个数据 我只想要最顶层的数据 您还可以看到其他行也可以展开 但在本例
  • 从 NumPy ndarray 中选择行

    我只想从 a 中选择某些行NumPy http en wikipedia org wiki NumPy基于第二列中的值的数组 例如 此测试数组的第二列包含从 1 到 10 的整数 gt gt gt test numpy array nump
  • import matplotlib.pyplot 给出 AttributeError: 'NoneType' 对象没有属性 'is_interactive'

    我尝试在 Pycharm 控制台中导入 matplotlib pyplt import matplotlib pyplot as plt 然后作为回报我得到 Traceback most recent call last File D Pr
  • 使用特定颜色和抖动在箱形图上绘制数据点

    我有一个plotly graph objects Box图 我显示了箱形 图中的所有点 我需要根据数据的属性为标记着色 如下所示 我还想抖动这些点 下面未显示 Using Box我可以绘制点并抖动它们 但我不认为我可以给它们着色 fig a
  • 如何使用原始 SQL 查询实现搜索功能

    我正在创建一个由 CS50 的网络系列指导的应用程序 这要求我仅使用原始 SQL 查询而不是 ORM 我正在尝试创建一个搜索功能 用户可以在其中查找存储在数据库中的书籍列表 我希望他们能够查询 书籍 表中的 ISBN 标题 作者列 目前 它
  • Python ImportError:无法导入名称 __init__.py

    我收到此错误 ImportError cannot import name life table from cdc life tables C Users tony OneDrive Documents Retirement retirem
  • 将 Python 中的日期与日期时间进行比较

    所以我有一个日期列表 datetime date 2013 7 9 datetime date 2013 7 12 datetime date 2013 7 15 datetime date 2013 7 18 datetime date
  • 如何计算Python中字典中最常见的前10个值

    我对 python 和一般编程都很陌生 所以请友善 我正在尝试分析包含音乐信息的 csv 文件并返回最常听的前 n 个乐队 从下面的代码中 每听一首歌曲都是一个列表中的字典条目 格式如下 album Exile on Main Street
  • 使用 z = f(x, y) 形式的 B 样条方法来拟合 z = f(x)

    作为一个潜在的解决方案这个问题 https stackoverflow com questions 76476327 how to avoid creating many binary switching variables in gekk

随机推荐

  • javascript动态更改图像src的位置 - 没有JQuery

    我有几个页面以相同的方式设置 每个页面大约有 10 到 15 张图像 如果单击它们 图像会发生变化并且变得无法单击 我为此的代码是 function ToggleOnclick elID var el document getElement
  • 如何在Python中读取文件的最后一行? [复制]

    这个问题在这里已经有答案了 我有两个要求 第一个要求 我想读取文件的最后一行并将最后一个值分配给python中的变量 第二个要求 这是我的示例文件
  • 获取 SQL Server 中的当前日期

    我进行了搜索 但无法找到获取这种格式的日期的方法 DD MM YYYY 请帮助我更改此请求 DECLARE date datetime set date 01 05 2016 SELECT User cast DATEADD SECOND
  • iOS6没有libxml2.2.7.3.dylib。有替代品吗?

    我在 xcode4 2 中创建了一个项目 当我用 xcode4 5 iOS 6 SDK 打开它时 它给出错误 255 原因似乎是缺少 libxml2 2 7 3 dylib 我有什么选择是否有其他替代品 thanks Xcode 4 5 或
  • 您最喜欢的 django 数据库迁移管理解决方案是什么? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我非常喜欢Rails 的数据库迁移管理系统 它不是 100 完美 但它确实有效 Django 还没有附
  • 替换字符串中最后一次出现的单词 - C#

    我有一个问题 我需要替换字符串中最后一次出现的单词 情况 我得到了一个格式如下的字符串 string filePath F jan11 MFrame Templates feb11 然后我替换TnaName像这样 filePath file
  • Android 手机卸载后会重新启动

    我正在开发一个应用程序 当我卸载手机时会出现半重启 这是我的旧帖子 我的手机有一个奇怪的问题 我使用的是三星 GALAXY 5 GT I5500 装有 Android 2 2 未 root 我是一名 Android 开发人员 我一直在开发非
  • .NET 配置节设计器 - 我的集合在哪里?

    我正在使用配置部分设计器 http csd codeplex com 为 NET构建一个简单的ConfigurationElementCollection It appears一切都构建得很好 并且代码是自动生成的 因为子元素通过 Inte
  • 查找所有出现的子字符串(包括重叠)?

    好的 所以我发现了这个 如何查找子字符串的所有出现位置 https stackoverflow com questions 4664850 find all occurrences of a substring in python 也就是说
  • 较大的 System.IO.MemoryStream 是否会导致应用程序的内存使用量急剧增加?

    我正在构建一个库 允许用户从 URL 下载文件 我正在考虑的选项之一是让用户指定文件的预期 MD5 校验和 该库的 GetFile string url 函数可确保下载的流的校验和与用户指定的校验和相匹配 意识到 HttpWebRespon
  • 缓存具有类似内存性能的数据集并将其与数据库更改相关联的最佳方法是什么?

    有人遇到过 Net 中的开源项目或库 它们充当数据库和应用程序之间的缓存层 自动或根据请求同步数据 从而提高性能 Net 堆栈有一些可以使用的功能 例如 Sql 依赖项和缓存 但两者都有问题 经过测试的替代方案 SqlDependency
  • 如何在生产中使用 Nginx 和 Unicorn 配置 ActionCable?

    我最近将我的 Rails 项目从 Rails4 切换到 5 0 0 beta3 以使用很棒的 ActionCable 我的 ActionCable 服务器在 unicorn 内部运行 在开发中一切正常 在生产中我有 Started GET
  • jquery .show('slow') 方向?

    是否可以改变方向 selector show slow and hide slow jQuery 中的效果 我可以定义其他效果的方向 例如幻灯片和剪辑 但没有显示或剪辑选项hide slow 我无法直接回复诺曼 乔伊纳帖子上的评论 没有足够
  • 异步控制台输出

    我的应用程序 win32 控制台有问题 控制台用于向我的应用程序发出命令 然而 它同时也用于输出日志消息 这些消息主要来自异步线程 当用户尝试写入一些输入并同时打印异步日志消息时 这会成为问题 从而影响用户输入的显示 我想就如何处理这种情况
  • 在angularjs中如何装饰$stateProvider Provider?

    这种类型的装饰器适用于services和工厂 我希望它也能与提供商合作 我尝试过以下装饰用户界面路由器 s stateProvider app config function provide provide decorator state
  • 扩展方法中的 HtmlAttributes

    我正在使用 MVC 5 并且正在尝试编写一些 Bootstrap 扩展方法 我的目标是 覆盖 Html ActionLink方法与Html BootstrapLinkButton The BootstrapLinkButton方法应该生成与
  • 在 NSArray 上使用下标时出现编译器错误“未找到预期方法”

    我编写了这个简单的代码来尝试新的 Objective C 文字语法NSArrays NSArray array foo NSLog array 0 第一行工作正常 但下标会导致错误 在 NSArray 类型的对象上找不到读取数组元素的预期方
  • 汤博乐开发工具

    我想创建 Tumblr 主题 有趣的是有没有 IDE Netbeans Eclipse PHPStorm 插件或开发工具 理想的情况是在浏览器中预览我的主题 而不将其上传到 Tumblr 谢谢 我找到了自己的方法来使用 PhpStorm 或
  • 使用 Winform 应用程序填写 PDF/表格

    我有一个 2 页的 PDF 我想使用 C NET Windows 应用程序在其上叠加信息 想象一下有人手动填写的表单 生成此表单后 需要对其进行预览和打印 导出为图形或 PDF 很好 但不是必需的 乍一看 我正在考虑两种方法来做到这一点 使
  • 如何从 Python 3.x 中的类定义将参数传递给元类?

    这是 Python 3 x 版本如何从类定义将参数传递给元类 https stackoverflow com questions 13762231 how to pass arguments to the metaclass from th