创建具有额外功能的自定义命名元组类型

2023-12-13

我想创建我自己类型的内置命名元组,它具有一些额外的功能。假设我们创建一个类:

from collections import namedtuple
MyClass = namedtuple('MyClass', 'field1 field2')

它是不可变的、可读的且简单的。现在我可以创建 MyClass 的实例:

myobj = MyClass(field1 = 1, field2 = 3.0)
print(myobj.field1, myobj.field2)

我的额外要求是创建实例时我想检查是否field1 is int类型和field2 is float。例如,如果用户尝试创建 MyClass 实例:

obj = MyClass(field1 = 1, field2 = 3.0) # instantiates ok
obj1 = MyClass(field1 = 'sometext', field2 = 3.0) # raises TypeError

我尝试制作一个自定义的命名元组,可以验证数据类型(MyClass 应该是不可变的),如下所示:

MyClass = modifiednamedtuple('MyClass', 'field1 field2', (int, float) )

但卡住了:(。namedtuple是函数(不能是修改后的nametuple的基类),我对元类的实验失败了。

有什么提示或建议吗?

好吧,我想出了一个可能不“干净”或Pythonic 的解决方案。它可以工作,只是我的对象不是一成不变的。如何使它们不可变?有什么建议如何使其更加干净和可红色吗?

这是我的代码:

def typespecificnamedtuple(name, *attr_definitions):

    def init(self, *args, **kwargs):
        valid_types = dict(attr_definitions) # tuples2dict
        for attr_name, value in kwargs.items():
            valid_type = valid_types[attr_name]
            if not isinstance(value, valid_type):
                raise TypeError('Cannot instantiate class '+ self.__name__+
                    '. Inproper datatype for '+ attr_name + '=' + str(value)+ 
                        ', expected '+str(valid_type) )
            setattr(self, attr_name, value)


    class_dict = {'__init__' : init, '__name__' : name}
    for attr_def in attr_definitions:
        class_dict[attr_def[0]] = attr_def[1] # attr_def is ('name', <type int>)

    customType = type(name, (object, ), class_dict )
    return customType

if __name__ == '__main__':
    MyClass = typespecificnamedtuple('MyClass', ('value', int), ('value2', float)  )
    mc = MyClass(value = 1, value2 = 3.0)
    mc.something = 1    # this assigment is possible :( how to make immutable?
    print(mc.__name__, mc.value, mc.value2, mc.something)
    mc1 = MyClass(value = 1, value2 = 'sometext')   # TypeError exception is raised

和控制台输出:

MyClass 1 3.0 1
Traceback (most recent call last):
  File "/home/pawel/workspace/prices/prices.py", line 89, in <module>
    mc1 = MyClass(value = 1, value2 = 'sometext')   # TypeError exception is raised
  File "/home/pawel/workspace/prices/prices.py", line 70, in init
    ', expected '+str(valid_type) )
TypeError: Cannot instantiate class MyClass. Inproper datatype for value2=sometext, expected <class 'float'>

namedtuple正如您所注意到的,不是一个类;这是一个函数。但它是一个返回类的函数。因此,您可以使用result of the namedtuple作为父类调用。

由于它是不可变的,namedtuple初始化于__new__而是在__init__.

所以,也许是这样的:

MyTuple = namedtuple('MyTuple', 'field1 field2')

class MyClass(MyTuple):
    def __new__(cls, field1, field2):
        if not isinstance(field1, int):
            raise TypeError("field1 must be integer")
        # accept int or float for field2 and convert int to float
        if not isinstance(field1, (int, float)):
            raise TypeError("field2 must be float")
        return MyTuple.__new__(cls, field1, float(field2))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建具有额外功能的自定义命名元组类型 的相关文章

随机推荐

  • Fluent NHibernate 将一列映射到两列之一

    我正在处理一些无法修改的旧供应商代码 我想用一个更易于使用的抽象层来包装数据库 给定以下两个表 我需要为 Process Route 创建一个映射 它将找到给定进程的匹配路由 但可以是 dbo Route SourceProcessID 或
  • iOS 5 中拖动 UIView

    我在 iPhone 应用程序中看到状态栏上有一个可以访问通知中心的手势 我如何在我的应用程序中实现这种转换 我认为这是通过滑动手势识别器完成的 但是如何包含从上到下的滑动手势 如何拖动通知中心完成其完整过渡 有任何示例代码或其他东西可以帮助
  • 使用字符数组作为字符串流缓冲区

    我正在寻找一种干净的 STL 方法来使用现有的 C 缓冲区 char 和 size t 作为字符串流 我更喜欢使用 STL 类作为基础 因为它具有内置的保护措施和错误处理 注意 我不能使用额外的库 否则我会使用文本流 你可以尝试使用std
  • django ALLOWED_HOSTS 不工作

    我的 settings py 文件包含 DEBUG False ALLOWED HOSTS u mydomainxxx com 但是 我可以像这样触发卷曲请求 curl X GET https mydomainxxx com api H A
  • PermissionError: [Errno 13] 权限被拒绝: '/code/manage.py'

    我试图在 docker 容器上运行 django 应用程序 按照以下提到的步骤操作https docs docker com compose django 但运行命令后docker compose run web django admin
  • 为什么这个 for 循环不处理完整的数据集?

    背景 我有一个活动门票分配的电子表格 电子表格的每一行都有一个名称和分配的票数 我需要更改电子表格 以便每个票证的每个名称在不同的行上重复一次 如下所示 我有一个宏可以做到这一点 但它表现出奇怪的行为 问题 该宏不会循环遍历整个数据集 单步
  • 强制 React-Router 加载页面,即使我们已经在该页面上

    有没有办法强制React Router从路径加载页面 即使当前位置已经是该页面 我似乎在反应路由器文档中找不到任何提及这一点的信息 我们在 申请 路线上有一个页面 该页面加载带有英雄图像 一些解释性文本等的登陆页面 以及一个 申请此计划 按
  • 自定义复选框首选项

    我无法自定义我的复选框 尽管我已经在 xml 首选项文件中定义了背景 但它不会提取该文件 1 我试图显示复选框的自定义图像 并将选择器 xml 定义为 android button xml 如下所示
  • JavaScript setInterval 和 this 解决方案

    我需要访问this从我的setInterval handler prefs null startup function init prefs this retrieve rate this intervalID setInterval th
  • pymysql callproc() 似乎影响后续选择

    我正在尝试将代码库从使用 MySQLdb 转换为 pymysql 我遇到了以下问题 想知道是否有人见过类似的问题 简而言之 如果我通过 pymysql 游标 callproc 方法调用存储过程 则使用相同或不同游标通过execute 方法进
  • 无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型

    我有一堂这样的课 public class MyStok public int STId get set public int SM get set public string CA get set public string Br get
  • Flutter Widgets 绑定观察者

    在 Flutter 中 我想返回到我离开应用程序的页面 但当我尝试返回时 它总是导航到登录页面 例如 我有 3 个页面 登录页面 锻炼页面 进度页面 登录页面是我的启动器 当我进入 ProgressPage 时 我离开了应用程序 但是当我恢
  • R:用 sub 替换多个正则表达式

    我有一个包含以下值的字符向量 1 tBodyAcc mean X tBodyAcc mean Y tBodyAcc mean Z tBodyAcc std X 5 tBodyAcc std Y tBodyAcc std Z tGravity
  • 在 WooCommerce 中隐藏特定运输类别的运输方式

    本质上我正在尝试使统一费率方法 Idflat rate 7 disabled当购物车商品的运输类别为 Roller ID92 这是我尝试过的代码 add filter woocommerce package rates wf hide sh
  • 如何创建可点击的列表视图并转到新页面

    我是一名新的安卓程序员 我想创建一个可点击的列表视图 我的意思是 当用户单击一个项目时 它会转到一个新页面并开始一项新活动 请帮我 提前致谢 这是我在 mainactivity java 中的代码 package first app imp
  • 错误:获取非对象的属性[重复]

    这个问题在这里已经有答案了 可能的重复 调用非对象的成员函数 我收到此错误 尝试获取非对象的属性 来自模型 当我尝试通过输入一个字符串从数据库检索 id 时 在本例中是 某物 这是我的模型 function getRoleId role n
  • 如何继承NilClass或者如何模拟类似的功能

    我只想使用空对象设计模式 但我发现我可以从 NilClass 继承 我可以写一个方法 nil 并返回 false 但如果用户在下面编写代码怎么办 if null object puts shouldn t be here end 为了澄清我
  • 如何禁用仅在一张特定图像上右键单击保存

    我正在运营一个亚洲电子商务网站 用户可以在其中发布其产品的图片 有没有办法禁用页面上仅 1 个特定图像的右键单击 例如 查看产品时 会看到一个大图像 然后是一些产品的缩略图 当尝试右键单击大图像时 我想禁用右键单击 但如果他们尝试右键单击缩
  • 使用 OpenCSV 解析 CSV,并在带引号的字段内添加双引号

    我正在尝试使用 OpenCSV 解析 CSV 文件 其中一列以 YAML 序列化格式存储数据 并用引号引起来 因为其中可以包含逗号 它里面也有引号 所以通过加两个引号来转义 我可以在 Ruby 中轻松解析该文件 但使用 OpenCSV 我无
  • 创建具有额外功能的自定义命名元组类型

    我想创建我自己类型的内置命名元组 它具有一些额外的功能 假设我们创建一个类 from collections import namedtuple MyClass namedtuple MyClass field1 field2 它是不可变的