可选关键字参数的命名元组和默认值

2023-12-01

我正在尝试将一个较长的空心“数据”类转换为命名元组。我的班级目前如下所示:

class Node(object):
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

转换后为namedtuple看起来像:

from collections import namedtuple
Node = namedtuple('Node', 'val left right')

但这里有一个问题。我原来的类允许我只传递一个值,并通过使用命名/关键字参数的默认值来处理默认值。就像是:

class BinaryTree(object):
    def __init__(self, val):
        self.root = Node(val)

但这对于我重构的命名元组不起作用,因为它希望我传递所有字段。我当然可以替换出现的情况Node(val) to Node(val, None, None)但这不符合我的喜好。

那么是否存在一个好的技巧可以使我的重写成功而不增加大量代码复杂性(元编程),或者我应该吞下药丸并继续“搜索和替换”? :)


Python 3.7

Use the defaults范围。

>>> from collections import namedtuple
>>> fields = ('val', 'left', 'right')
>>> Node = namedtuple('Node', fields, defaults=(None,) * len(fields))
>>> Node()
Node(val=None, left=None, right=None)

或者更好的是,使用新的数据类库,它比namedtuple好得多。

>>> from dataclasses import dataclass
>>> from typing import Any
>>> @dataclass
... class Node:
...     val: Any = None
...     left: 'Node' = None
...     right: 'Node' = None
>>> Node()
Node(val=None, left=None, right=None)

Python 3.7 之前

Set Node.__new__.__defaults__为默认值。

>>> from collections import namedtuple
>>> Node = namedtuple('Node', 'val left right')
>>> Node.__new__.__defaults__ = (None,) * len(Node._fields)
>>> Node()
Node(val=None, left=None, right=None)

Python 2.6 之前

Set Node.__new__.func_defaults为默认值。

>>> from collections import namedtuple
>>> Node = namedtuple('Node', 'val left right')
>>> Node.__new__.func_defaults = (None,) * len(Node._fields)
>>> Node()
Node(val=None, left=None, right=None)

Order

在 Python 的所有版本中,如果您设置的默认值少于命名元组中存在的值,则默认值将应用于最右侧的参数。这允许您保留一些参数作为必需参数。

>>> Node.__new__.__defaults__ = (1,2)
>>> Node()
Traceback (most recent call last):
  ...
TypeError: __new__() missing 1 required positional argument: 'val'
>>> Node(3)
Node(val=3, left=1, right=2)

Python 2.6 到 3.6 的包装器

这是一个适合您的包装器,它甚至可以让您(可选)将默认值设置为除None。这不支持必需的参数。

import collections
def namedtuple_with_defaults(typename, field_names, default_values=()):
    T = collections.namedtuple(typename, field_names)
    T.__new__.__defaults__ = (None,) * len(T._fields)
    if isinstance(default_values, collections.Mapping):
        prototype = T(**default_values)
    else:
        prototype = T(*default_values)
    T.__new__.__defaults__ = tuple(prototype)
    return T

Example:

>>> Node = namedtuple_with_defaults('Node', 'val left right')
>>> Node()
Node(val=None, left=None, right=None)
>>> Node = namedtuple_with_defaults('Node', 'val left right', [1, 2, 3])
>>> Node()
Node(val=1, left=2, right=3)
>>> Node = namedtuple_with_defaults('Node', 'val left right', {'right':7})
>>> Node()
Node(val=None, left=None, right=7)
>>> Node(4)
Node(val=4, left=None, right=7)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可选关键字参数的命名元组和默认值 的相关文章

随机推荐

  • 为什么 OS X 上的 FF 在单击事件处理程序中丢失了 jQuery-UI?

    在使用 jQUery 1 7 1 和 jQUery UI 1 8 18 的网页中 如果我在文档准备好时在警报框中输出 ui 我会得到 object Object 但是 当使用 Firefox 时 如果我在单击事件处理程序中输出 ui 则会得
  • 重用 UITableView 中的单元格

    我有我的自定义单元 NewsCell 它包含我的自定义视图 ImageMosaicView 它只是 UIView 的子类 我用它来显示照片 就像 Facebook 上发布的照片 一样 我只是将图像的 url 传递给 ImageMosaicV
  • C++成员函数隐藏的原因[重复]

    这个问题在这里已经有答案了 可能的重复 名称隐藏和脆弱的基础问题 我熟悉涉及成员函数隐藏的规则 基本上 具有与基类函数同名的函数的派生类实际上不会重载基类函数 它完全隐藏了它 struct Base void foo int x const
  • 我如何用 throw e 在开玩笑行中进行测试?

    如何在玩笑错误情况下进行测试 这就是我所做的 我不知道是否存在一种方法来测试这个 it the fetch fails and throw an error async gt let response status 400 body bas
  • Javascript API 不适用于 JW Player 5.9 上的 Chrome 或 Safari

    我正在为 JW Player 开发一个自定义界面 它显示当前曲目标题并具有播放 暂停 下一曲目 上一曲目和音量切换按钮 它适用于 IE8 9 和 FF 但不适用于 Chrome 和 Safari Chrome 的控制台出现以下错误 未捕获的
  • 将输出写入不同的文件夹 hadoop

    我想将同一个减速器的两种不同类型的输出写入两个不同的目录 我可以使用 hadoop 中的多输出功能写入不同的文件 但它们都转到相同的输出文件夹 我想将同一个reduce 中的每个文件写入不同的文件夹 有办法做到这一点吗 如果我尝试将 hel
  • 为什么方法 Base64.encodeBase64String(byte) 不可用

    您好 我已将官方网页中的 apache commons codec 1 7 jar 添加到我的项目构建路径中 但该方法Base64 encodeBase64String byte当我编写代码时不可用 我已经用旧版本的 jar 1 5 1 6
  • 动态加载 php 扩展而不使用 dl() 函数?

    这可能吗 如果可能的话 该怎么做 我问是因为dl 我无法使用该函数 因为 PHP 团队正在从后续版本中放弃该函数 请不要回答 改用扩展加载指令 这正是我不明白的部分 我想 我要问 The 函数已从所有 SAPI 中删除other自 PHP
  • php 命令行性能缓慢 - 这是正常现象还是我有安装问题?

    我有一个简单的 PHP 应用程序 可以打印 hello world 当我从命令行运行它时 需要 6 秒 这是正常的吗 似乎需要 1 秒才能打印 hello world 然后又需要 5 秒 我在 Windows Server 2008 R2
  • 链接升压日志教程时出现链接器错误(未定义的引用)

    我已经通过 yum 在 Fedora 20 上安装了 boost 并且正在尝试一些简单的示例 但是我在编译第一个示例时遇到了麻烦日志记录教程 编译用g c boosttest cc工作正常 但是当我尝试将其链接到时出现很多错误 g boos
  • 在 HQL 上使用 select 进行内连接

    我想用 HQL 做类似的事情 SELECT FROM tableA a INNER JOIN select fieldA sum fieldB as sum from tableB b ON a fieldA b fieldA and a
  • 为什么 Class 变量没有更新其所有实例?

    我正在学习课程 但不明白这一点 class MyClass var 1 one MyClass two MyClass print one var two var out 1 1 one var 2 print one var two va
  • MultiView Android Delphi 与 TWebBrowser

    在包含 TWebBrowser 的区域中使用 MultiView 组件 该组件会覆盖 MultiView 有没有办法来解决这个问题 用法 德尔福XE8更新1 第一个测试中没有代码 所有配置均通过 MultiView 实现可视化 使用 TWe
  • UIView动画在动画过程中确定中心

    我正在使用 UIView 的 animateWithDuration delay options animations completion 方法在几秒钟左右的时间内沿着一条线移动我的视图 我想在该动画期间的任意时间确定 UIView 及其
  • 如何将数组从一个 Servlet 传递到另一个 Servlet?

    我想将多个值从一个 servlet 传递到另一个 servlet 请告诉我如何通过 You can 使用以下命令将数组作为属性放入请求上下文中request setAttribute 使用以下命令将请求转发到第二个 servletReque
  • 宏 ((void(*)())0)() 是什么意思?

    以下宏的结果很清楚 define CRASH do int uintptr t 0xbbadbeef 0 void 0 while false 我的问题是 这条线是什么 void 0 分解为 用英语 例如 这是一个返回指向 的指针的函数 看
  • 如何消除应用栏上的弹跳效果?

    应用栏过去在滑动时会出现问题 它滚动得不顺畅 请参考这些 http stackoverflow com questions 30923889 flinging with recyclerview appbarlayout https git
  • 查询在函数内部不起作用

    嗯 我在 SMF 的自定义脚本中有这个函数 query SELECT id member real name id group FROM smf members WHERE id group gt 0 AND id group 9 AND
  • 如何垂直居中 Bootstrap 轮播标题?

    我有一个引导轮播 我正在尝试为轮播创建一个标题 该标题始终垂直居中并稍微向左定位 我有用于水平定位的CSS 但是当我尝试垂直定位时 标题不会保持原样 如何保持 carousel caption 始终垂直居中并稍微偏左 HTML div cl
  • 可选关键字参数的命名元组和默认值

    我正在尝试将一个较长的空心 数据 类转换为命名元组 我的班级目前如下所示 class Node object def init self val left None right None self val val self left lef