当前位置: 首页 > 知识库问答 >
问题:

Python:扩展预定义的命名元组

罗法
2023-03-14

我有以下命名元组:

from collections import namedtuple
ReadElement = namedtuple('ReadElement', 'address value')

然后我想要以下内容:

LookupElement = namedtuple('LookupElement', 'address value lookups')

两个名称元组之间有重复,我如何子类ReadElement以包含一个附加字段?

class LookupElement(ReadElement):
    def __new__(self, address, value, lookups):
        self = super(LookupElement, self).__new__(address, value)
        l = list(self)
        l.append(lookups)
        return tuple(l)

然而元组是创建在那里的,那么在新语句中,如果我修改自我成为一个列表,我会失去类型信息,我该如何避免这种情况?

共有3个答案

谭勇
2023-03-14

很容易将一些东西组合在一起,允许您从其他名称元组组成名称元组以及引入新字段。

def extended_namedtuple(name, source_fields):
    assert isinstance(source_fields, list)
    new_type_fields = []
    for f in source_fields:
        try:
            new_type_fields.extend(f._fields)
        except:
            new_type_fields.append(f) 
    return namedtuple(name, new_type_fields) 

# source types
Name = namedtuple('Name', ['first_name', 'last_name'])
Address = namedtuple('Address', ['address_line1', 'city'])
# new type uses source types and adds additional ID field
Customer = extended_namedtuple('Customer', ['ID', Name, Address])
# using the new type
cust1 = Customer(1, 'Banana', 'Man', '29 Acacia Road', 'Nuttytown')
print(cust1)

这将输出以下内容:

Customer(ID=1, first_name='Banana', last_name='Man', address_line1='29 Acacia Road', city='Nuttytown')
韩麒
2023-03-14

扩展Martijn Pieters的答案:有一种方法可以使新的namedtuple类成为另一个类的子类,而无需破解。只需单独创建新的namedtuple,然后使用其__new__方法而不是使用Super

from collections import namedtuple

class ReadElement(namedtuple('ReadElement', ('address', 'value'))):
    def compute(self):
        return self.value + 1

_LookupElement = namedtuple('_LookupElement', ReadElement._fields + ('lookups',))

class LookupElement(_LookupElement, ReadElement):
    def __new__(self, address, value, lookups):
        return _LookupElement.__new__(LookupElement, address, value, lookups)

assert issubclass(LookupElement, ReadElement)
l = LookupElement('ad', 1, dict())
assert isinstance(l, ReadElement)
assert l.compute() == 2

这似乎也可以在没有覆盖__new__的情况下工作!

from collections import namedtuple

class ReadElement(namedtuple('ReadElement', ('address', 'value'))):
    def compute(self):
        return self.value + 1

class LookupElement(namedtuple('LookupElement', ReadElement._fields + ('lookups',)),
                    ReadElement):
    """nothing special to do"""
    pass
隆钊
2023-03-14

您可以子类化< code>namedtuple生成的类,但是您需要更仔细地研究生成的类。您需要添加另一个具有额外字段的< code>__slots__属性,更新< code>_fields属性,创建新的< code>__repr__和< code>_replace方法(它们硬编码字段列表和类名),并为额外的字段添加额外的< code>property对象。请参见文档中的示例。

这一切都有点太多了。而不是子类,我只是重用源类型的somenamedtuple._fields属性:

LookupElement = namedtuple('LookupElement', ReadElement._fields + ('lookups',))

< code>namedtuple()构造函数的< code>field_names参数不一定是字符串,也可以是字符串序列。只需获取< code>_fields并通过连接一个新元组来添加更多元素。

演示:

>>> from collections import namedtuple
>>> ReadElement = namedtuple('ReadElement', 'address value')
>>> LookupElement = namedtuple('LookupElement', ReadElement._fields + ('lookups',))
>>> LookupElement._fields
('address', 'value', 'lookups')
>>> LookupElement('addr', 'val', 'lookup') 
LookupElement(address='addr', value='val', lookups='lookup')

这意味着扩展类型不是基类型的子类。如果您必须有一个类层次结构,那么与其尝试使命名元组适合该模型,不如改为使用数据类。在大多数使用元组的用例中,数据类可以起到相同的作用,但可以很容易地进行子类化。

 类似资料:
  • 我的web服务有一个很大的问题。 贝斯特,杰彭

  • 目前 Mars 支持自定义 xlog 的加密部分和长短连协议加解包部分。需要强调的是想要自定义这些扩展,需要在本地编译 Mars 才可以,编译方法见 Mars Android 接入指南 和 Mars iOS/OS X 接入指南 中的编译部分。切记,在自定义实现时,可以增加函数,但是不能删除头文件中已有的函数,也不能修改头文件中的函数原型。 自定义 xlog 加密 xlog 的具体实现可以参考微信终

  • 扩展包需要预先定义好所有功能以及一些基础信息,这些信息都需要填写并存放在 package.json 文件里。 { "name": "hello-world", "version": "1.0.0", "author": "Creator", "description": "description", "main": "./browser.js",

  • 就给定的表、数据和索引,要求存储引擎为MySQL服务器提供存储引擎所使用的扩展列表。 扩展应采用以Null终结的字符串数组形式。下面给出了CSV引擎使用的数组: static const char *ha_tina_exts[] = { ".CSV", NullS }; 调用bas_ext()函数时返回该数组。 const char **ha_tina::bas_ext() const {

  • 当我们在开发某些东西时,经常会需要我们自己的 error 类来反映在我们的任务中可能出错的特定任务。对于网络操作中的 error,我们需要 HttpError,对于数据库操作中的 error,我们需要 DbError,对于搜索操作中的 error,我们需要 NotFoundError,等等。 我们自定义的 error 应该支持基本的 error 的属性,例如 message,name,并且最好还有

  • 问题内容: 有没有办法将Python元组扩展为函数-作为实际参数? 例如,这里做了魔术: 我知道可以将其定义,但是当然可能会有遗留代码。谢谢 问题答案: 不正是你要求什么。的*操作者只需解包元组(或任何可迭代),并把它们作为位置函数的自变量。有关更多信息,请参见此处。 侧问题:不要为你的标识符内建类型的名称,如使用,,,,等等-这是可怕的做法,它会回来,咬你的时候,你最不经意的时候,所以只是进入的