如何在Python中创建第二个None?创建一个 id 始终相同的单例对象

2023-12-11

警告:以下问题要求提供有关不良做法和脏代码的信息。建议开发商酌情决定。

注意:这与在 Python 中创建单例问题是因为我们想要解决酸洗和复制以及正常的对象创建问题。

目标:我想创造一个价值(称为NoParam)模拟的行为None。具体来说,我想要任何实例NoParamType具有相同的值 --- 即具有相同的id- - 所以这样is运算符总是返回True在这两个值之间。

原因:我有保存参数值的配置类。其中一些参数可以采用None作为有效类型。但是,如果未指定类型,我希望这些参数采用特定的默认值。因此我需要一些哨兵is not None来指定没有指定参数。这个哨兵需要是这样的东西 永远不能用作有效的参数值。我更愿意为这个哨兵使用特殊类型,而不是使用一些不太可能使用的字符串。

例如:

def add_param(name, value=NoParam):
    if value is NoParam:
        # do some something
    else:
        # do something else 

但我们不必太担心原因。让我们重点讨论如何做。


到目前为止我所拥有的:

我可以很容易地实现大部分这种行为。我创建了一个名为的特殊模块util_const.py。它包含一个创建 NoParamType 的类,然后创建该类的单例实例。

class _NoParamType(object):
    def __init__(self):
        pass

NoParam = _NoParamType()

我只是假设永远不会创建此类的第二个实例。每当我想使用我的值时import util_const并使用util_const.NoParam.

这对于大多数情况都很有效。然而我刚刚遇到一个案例 ANoParamvalue 被设置为对象值。使用深度复制该对象copy.deepcopy因此创建了第二个 NoParam 实例。

我找到了一个非常简单的解决方法,通过定义__copy__ and __deepcopy__ methods

class _NoParamType(object):
    def __init__(self):
        pass
    def __copy__(self):
        return NoParam
    def __deepcopy__(self, memo):
        return NoParam

NoParam = _NoParamType()

Now, if deepcopy曾经被称为“不”NoParam它只是返回现有的NoParam实例。


现在问题是:

我可以做些什么来通过酸洗实现同样的行为吗?最初我以为我可以定义__getstate__但此时第二个实例已经创建。本质上我想要pickle.loads(pickle.dumps(NoParam)) is NoParam返回 True。有没有办法做到这一点(也许使用元类)?

更进一步:我能做些什么来确保只创建一个 NoParam 实例吗?


Solution

非常感谢@user2357112回答有关酸洗的问题。 我还弄清楚了如何使此类对模块重新加载也具有鲁棒性。这是我所学到的全部内容

# -*- coding: utf-8 -*-
# util_const.py    

class _NoParamType(object):
    """
    Class used to define `NoParam`, a setinal that acts like None when None
    might be a valid value. The value of `NoParam` is robust to reloading,
    pickling, and copying.  

    Example:
        >>> import util_const
        >>> from util_const import _NoParamType, NoParam
        >>> from six.moves import cPickle as pickle
        >>> import copy
        >>> versions = {
        ... 'util_const.NoParam': util_const.NoParam,
        ... 'NoParam': NoParam,
        ... '_NoParamType()': _NoParamType(),
        ... 'copy': copy.copy(NoParam),
        ... 'deepcopy': copy.deepcopy(NoParam),
        ... 'pickle': pickle.loads(pickle.dumps(NoParam))
        ... }
        >>> print(versions)
        >>> assert all(id(v) == id_ for v in versions.values())
        >>> import imp
        >>> imp.reload(util_const)
        >>> assert id(NoParam) == id(util_const.NoParam)
    """
    def __new__(cls):
        return NoParam
    def __reduce__(self):
        return (_NoParamType, ())
    def __copy__(self):
        return NoParam
    def __deepcopy__(self, memo):
        return NoParam
    def __call__(self, default):
        pass

# Create the only instance of _NoParamType that should ever exist
# When the module is first loaded, globals() will not contain NoParam. A
# NameError will be thrown, causing the first instance of NoParam to be
# instanciated.
# If the module is reloaded (via imp.reload), globals() will contain
# NoParam. This skips the code that would instantiate a second object
# Note: it is possible to hack around this via
# >>> del util_const.NoParam
# >>> imp.reload(util_const)

try:
    NoParam
except NameError:
    NoParam = object.__new__(_NoParamType)

我可以做些什么来通过酸洗实现同样的行为吗?

Yes.

class _NoParamType(object):
    def __new__(cls):
        return NoParam
    def __reduce__(self):
        return (_NoParamType, ())

NoParam = object.__new__(_NoParamType)

更进一步:我能做些什么来确保只创建一个 NoParam 实例吗?

不写就不行NoParam除非你用 C 编写并利用 C API-only 功能,否则总是可以做到object.__new__(type(NoParam))获取另一个实例。

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

如何在Python中创建第二个None?创建一个 id 始终相同的单例对象 的相关文章

  • xlrd.biffh.XLRDError:Excel xlsx 文件;不支持[重复]

    这个问题在这里已经有答案了 我正在尝试使用读取启用宏的 Excel 工作表pandas read excel与 xlrd 库 它在本地运行良好 但是当我尝试将其推送到 PCF 时 我收到此错误 2020 12 11T21 09 53 441
  • 切片稀疏(scipy)矩阵

    我将不胜感激任何帮助 以理解从 scipy sparse 包中切片 lil matrix A 时的以下行为 实际上 我想根据行和列的任意索引列表提取子矩阵 当我使用这两行代码时 x1 A list 1 x2 x1 list 2 一切都很好
  • Kivy - 文本换行工作错误

    我正在尝试在 Kivy 1 8 0 应用程序中换行文本 当没有太多文字时 一切正常 但如果文本很长并且窗口不是很大 它只是剪切文本 这是示例代码 vbox BoxLayout orientation vertical size hint y
  • 为什么我的代码不能根据字典解码加密字符串?

    我有一本字典 其中包含代表字母的键和值 例如一个简单的 DICT CODE b g n a p o x d t y 我收到了一个加密代码 并将该字符串转换为一个列表 其中每个项目都是一个单词 我需要根据字典中的项目来解决它 代码示例是 wo
  • 如何在 Python 3 中循环遍历集合,同时从集合中删除项目

    这是我的情况 我有一个list set 哪个并不重要 movieplayer我想调用的对象 preload 功能开启 该预加载函数可以立即返回 但希望将来返回一点 我想存储这个电影播放器 集合 表明它们尚未预加载 然后循环它们 调用prel
  • PySide6.1 与 matplotlib 3.4 不兼容

    当我只安装PySide6时 GUI程序运行良好 但是一旦我安装了matplotlib及其依赖包 包括pyqt5 则GUI程序将无法运行并输出以下错误消息 This application failed to start because no
  • 动态 __init_subclass__ 方法的参数绑定

    我正在尝试让类装饰器工作 装饰器会添加一个 init subclass 方法到它所应用的类 但是 当该方法动态添加到类中时 第一个参数不会绑定到子类对象 为什么会发生这种情况 举个例子 这是可行的 下面的静态代码是我试图最终得到的示例 cl
  • 与 while 循环一样,如何跳过 for 循环中的步骤?

    我尝试像 while 循环一样跳过 for 循环中的几个步骤 在 while 循环中 步骤根据特定条件进行调整 如下面的代码所示 i 0 while i lt 10 if i 3 i 5 else print i i i 1 result
  • 乘以行并按单元格值附加到数据框

    考虑以下数据框 df pd DataFrame X a b c d Y a b d e Z a b c d 1 2 1 3 df 我想在 列中附加数字大于 1 的行 并在该行中的数字减 1 df 最好应该 然后看起来像这样 或者它可能看起来
  • Python 惰性迭代器

    我试图了解迭代器表达式如何以及何时被求值 以下似乎是一个懒惰的表达 g i for i in range 1000 if i 3 i 2 然而 这个在构造上失败了 g line strip for line in open xxx r if
  • 具有屏蔽无效值的 pcolormesh

    我试图将一维数组绘制为 pcolormesh 因此颜色沿 x 轴变化 但每个 x 的 y 轴保持不变 但我的数据有一些错误值 因此我使用屏蔽数组和自定义颜色图 其中屏蔽值设置为蓝色 import numpy as np import mat
  • Python 声音(“铃声”)

    我想让一个 python 程序在完成任务时通过发出嘟嘟声来提醒我 目前 我使用import os然后使用命令行语音程序说 进程完成 我更愿意它是一个简单的 铃 我知道有一个函数可以用于Cocoa apps NSBeep 但我认为这与此没有太
  • 如何使用 Keras ImageDataGenerator 预测单个图像?

    我已经训练 CNN 对图像进行 3 类分类 在训练模型时 我使用 keras 的 ImageDataGenerator 类对图像应用预处理功能并重新缩放它 现在我的网络在测试集上训练得非常准确 但我不知道如何在单图像预测上应用预处理功能 如
  • 检测 IDLE 的存在/如何判断 __file__ 是否未设置

    我有一个脚本需要使用 file 所以我了解到 IDLE 没有设置这个 有没有办法从我的脚本中检测到 IDLE 的存在 if file not in globals file is not set 如果你想做一些特别的事情 file 未设置
  • 如何使用 matplotlib 为圆柱体的每个单独面添加颜色

    我正在尝试为圆柱体的每个面着色 但是我不确定如何进行 我尝试了以下方法 for i in range 10 col append for i in range 10 for j in range 20 col i append plt cm
  • 如何在 robobrowser-python 中发出 POST 请求

    http robobrowser readthedocs org en latest api html http robobrowser readthedocs org en latest api html 我正在尝试使用 APIbrows
  • 更改 Python Cmd 模块处理自动完成的方式

    我有一个 Cmd 控制台 设置为自动完成 Magic the Gathering 收藏管理系统的卡牌名称 它使用文本参数在数据库中查询卡片 并使用结果自动完成 建议卡片 然而 这些卡片名称有多个单词 Cmd 会从last到行尾的空间 例如
  • Python 通过从现有 csv 文件中过滤选定的行来写入新的 csv 文件

    只是一个问题 我试图将 csv 文件中的选定行写入新的 csv 文件 但出现错误 我试图读取的 test csv 文件是这样的 两列 2013 9 1 2013 10 2 2013 11 3 2013 12 4 2014 1 5 2014
  • Python:高精度time.sleep

    你能告诉我如何在 Win32 和 Linux 上的 Python 2 6 中获得高精度睡眠函数吗 您可以在中使用浮点数sleep http docs python org library time html time sleep 该参数可以
  • Django 模型:如何使用 mixin 类来覆盖 django 模型以实现 save 等功能

    我想在每次保存模型之前验证值 所以 我必须重写保存函数 代码几乎是一样的 我想把它写在 mixin 类中 但失败了 我不知道如何写 super func 我英语不好 抱歉 class SyncableMixin object def sav

随机推荐

  • 在日历应用程序中对重复事件进行建模的最佳方法是什么? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我正在构建一个需要支持重复事件的组日历应用程序 但我想出的用于处理这些事件的所有解决方案似乎都是黑客 我可以限制一个人可以看到的距离 然后立即生成所有事件 或者 我可以将事件存储为重复事件
  • 如何禁用“调试”在 package.json 中显示

    如何禁止在上面的 package json 中显示概述的 调试 提示scripts部分 设置为 debug javascript codelens npmScripts never 由于它显示为scripts我搜索的 package jso
  • 将项目标记为特定类别

    我想根据项目中的文本将项目标记为特定类别 我有以下代码 Sub ProcessRSS Read RSS items and process the usful ones Dim objList As Object Dim objItem A
  • Coldfusion 9 使用哪个版本的 iText?

    ColdFusion 9 使用哪个版本的 iText 并不明显 有任何想法吗 ColdFusion 9 0 1 附带 iText 2 1 0 由 lowagie com 提供 您可以在此处找到 ColdFusion 脚本来确定版本 http
  • 如何计算VBA中一个字符串出现在另一个字符串中的次数?

    如何计算 Access VBA 中一个字符串出现在另一个字符串中的次数 例如 我如何计算 The Quick Brown Fox Jumps Over the Lazy Dog 中 The 出现了多少次 因为您对子字符串 区分大小写没问题
  • 从 forEach 推送对象后数组保持为空

    需要帮助 我遇到数组保持空的问题从 forEach 推送对象后 我是否错过了什么 这是代码 const allStatus result forEach async element gt const count await BpCandid
  • 使用 Mac App Store 中 Safari 组件的应用程序的导出合规性

    我正在向 Mac App Store 提交一个应用程序 该应用程序使用 Safari 组件来显示网页 我被问到这个问题 您的应用程序是否设计为使用加密技术 或者是否包含或合并加密技术 即使您的应用程序仅使用 iOS 或 OS X 中提供的加
  • Swift - 整数转换为小时/分钟/秒

    我有一个 有点 关于时间转换的基本问题Swift 我有一个整数 我想将其转换为小时 分钟 秒 Example Int 27005会给我 7 Hours 30 Minutes 5 Seconds 我知道如何在 PHP 中执行此操作 但可惜 S
  • 打开抽屉菜单时重建脚手架主体

    我有一个有状态的小部件 它构建了一个脚手架 我在脚手架中使用一个抽屉作为侧面菜单 此外 Scaffold 的主体是一个 FutureBuilder 它从 firestore 数据库获取数据并将信息显示在主体的卡片中 打开抽屉时似乎出现问题
  • SQL 中“AS”是什么意思?

    下面是概要SELECT来自 PostgreSQL文档 在我看来 有时我们会写
  • DateTime 和 ASP.NET MVC 3 模型绑定的全球化问题

    我的应用程序在 ro RO 区域性设置下运行 在 web config 全球化部分中配置 如果我发出像这样的 POST 请求 POST myapp index date 03 12 2010 value something 模型绑定将此映射
  • IE8 在 JavaScript 弹出窗口上奇怪地崩溃

    创建弹出窗口后我遇到一个奇怪的问题onclick 弹出窗口打开 但在 IE8 上立即挂起 在包括 IE6 在内的所有其他浏览器上工作正常 但在添加alert如 JavaScript 代码中所示 弹出窗口工作正常 我在用 https 并不是
  • 如何在 TypeScript 中定义 Singleton

    在 TypeScript 中为类实现单例模式的最佳和最方便的方法是什么 有或没有延迟初始化 从 TS 2 0 开始 我们有能力定义构造函数的可见性修饰符 所以现在我们可以在 TypeScript 中执行单例 就像我们习惯在其他语言中一样 给
  • 非空约束上的 Hibernate JoinColumn 错误

    这是我的课程列表 MappedSuperclass public abstract class JpaModel Id Column name ID columnDefinition serial GeneratedValue strate
  • 除了 Davg 之外还有其他求平均值的方法吗?

    我在工作中继承了这个访问数据库 我正在寻找一种更快的方法来编写一些代码 目前运行该程序大约需要 1 5 分钟 我需要它更快 目前我已将其全部设置为 DAvg 和 DCount 但问题是它基本上打开和关闭其使用的每一行的查询 就其本身而言很好
  • Weblogic Prefer 应用程序包不工作

    我使用的是Weblogic 10 3 6门户服务器 Weblogic 10 3 6始终使用weblogic附带的common fileupload jar 但我希望服务器使用我在战争中拥有的服务器 用例是我有 war1 它使用 war2 内
  • 如果类型与类型说明符不匹配,printf 如何工作?

    int main printf c n return 0 这里根据类型说明符需要一个字符 但我们正在通过它const char 我希望它会在代码块 GNU GCC 编译器中给我一条警告消息 但它没有给我任何警告并打印 特点 为什么它不发出任
  • VS2010 中的扩展管理器错误?

    当我尝试从 VS2010 Ultimate 打开扩展管理器时 出现此错误 指定的路径 文件名或两者都太长 完全限定文件名 Microsoft Visual Studio 必须少于 260 个字符 目录名必须少于 248 个字符 我之前曾使用
  • 选择列时出现 KeyError

    我试图调用一个字段并收到错误 调用该表中的任何字段都会出现相同的错误 df ret pd read csv Retention Data csv na values print df ret Cohorts Retention Rate 这
  • 如何在Python中创建第二个None?创建一个 id 始终相同的单例对象

    警告 以下问题要求提供有关不良做法和脏代码的信息 建议开发商酌情决定 注意 这与在 Python 中创建单例问题是因为我们想要解决酸洗和复制以及正常的对象创建问题 目标 我想创造一个价值 称为NoParam 模拟的行为None 具体来说 我