使具有不可选取字段的对象可选取的正确方法是什么?

2023-11-24

对我来说,我所做的就是检测不可选取的内容并将其放入字符串中(我想我也可以将其删除,但随后它会错误地告诉我该字段不存在,但我宁愿让它存在但成为字符串) )。但我想知道是否有一种不那么老套、更正式的方式来做到这一点。

我当前使用的代码:

def make_args_pickable(args: Namespace) -> Namespace:
    """
    Returns a copy of the args namespace but with unpickable objects as strings.

    note: implementation not tested against deep copying.
    ref:
        - https://stackoverflow.com/questions/70128335/what-is-the-proper-way-to-make-an-object-with-unpickable-fields-pickable
    """
    pickable_args = argparse.Namespace()
    # - go through fields in args, if they are not pickable make it a string else leave as it
    # The vars() function returns the __dict__ attribute of the given object.
    for field in vars(args):
        field_val: Any = getattr(args, field)
        if not dill.pickles(field_val):
            field_val: str = str(field_val)
        setattr(pickable_args, field, field_val)
    return pickable_args

背景:我认为我这样做主要是为了删除我随身携带的烦人的张量板对象(但我认为我不需要.tb领域不再感谢wandb/权重和偏差)。这并不是很重要,但背景总是好的。

Related:

  • 对象可腌制(或可腌制)意味着什么?
  • Python - 如何使这个不可腌制的对象可腌制?

Edit:

由于我决定放弃 dill - 因为有时它无法恢复类/对象(可能是因为它无法保存他们的代码或其他东西) - 我决定只使用pickle(这似乎是 PyTorch 中推荐的方法)。

那么,检查没有莳萝或官方泡菜的可采摘物的官方(可能是优化的)方法是什么?

这是最好的吗:

def is_picklable(obj):
  try:
    pickle.dumps(obj)

  except pickle.PicklingError:
    return False
  return True

因此当前的解决方案:

def make_args_pickable(args: Namespace) -> Namespace:
    """
    Returns a copy of the args namespace but with unpickable objects as strings.

    note: implementation not tested against deep copying.
    ref:
        - https://stackoverflow.com/questions/70128335/what-is-the-proper-way-to-make-an-object-with-unpickable-fields-pickable
    """
    pickable_args = argparse.Namespace()
    # - go through fields in args, if they are not pickable make it a string else leave as it
    # The vars() function returns the __dict__ attribute of the given object.
    for field in vars(args):
        field_val: Any = getattr(args, field)
        # - if current field value is not pickable, make it pickable by casting to string
        if not dill.pickles(field_val):
            field_val: str = str(field_val)
        elif not is_picklable(field_val):
            field_val: str = str(field_val)
        # - after this line the invariant is that it should be pickable, so set it in the new args obj
        setattr(pickable_args, field, field_val)
    return pickable_args


def make_opts_pickable(opts):
    """ Makes a namespace pickable """
    return make_args_pickable(opts)


def is_picklable(obj: Any) -> bool:
    """
    Checks if somehting is pickable.

    Ref:
        - https://stackoverflow.com/questions/70128335/what-is-the-proper-way-to-make-an-object-with-unpickable-fields-pickable
    """
    import pickle
    try:
        pickle.dumps(obj)
    except pickle.PicklingError:
        return False
    return True

注意:我想要“官方”/测试的原因之一是因为我在 try catch 上停止了 pycharm:如何在已处理的异常上停止 PyCharm 的中断/停止/停止功能(即仅在 python 未处理的异常上中断)?这不是我想要的......我希望它只在未处理的异常上停止。


使具有不可选取字段的对象可选取的正确方法是什么?

我相信这个问题的答案属于您链接的问题 -Python - 如何使这个不可腌制的对象可腌制?。我添加了一个新答案这个问题解释了如何以正确的方式使不可腌制的对象可腌制,而不使用__reduce__.

那么,检查没有莳萝或官方泡菜的可采摘物的官方(可能是优化的)方法是什么?

可picklable 的对象在文档中定义如下:

  • None, True, and False
  • 整数、浮点数、复数
  • 字符串、字节、字节数组
  • 仅包含可腌制对象的元组、列表、集合和字典
  • 在模块顶层定义的函数(使用def, not lambda)
  • 在模块顶层定义的内置函数
  • 在模块顶层定义的类
  • 此类类的实例dict或调用的结果getstate() 是可腌制的(有关详细信息,请参阅腌制类实例部分)。

棘手的部分是(1)知道函数/类是如何定义的(您可能可以使用inspect模块)和(2)通过对象递归,根据上述规则进行检查。

对此有很多注意事项,例如泡菜协议版本,该对象是扩展类型(例如在 numpy 等 C 扩展中定义的)还是“用户定义”类的实例。的用法__slots__还可以影响对象是否可腌制(因为__slots__意味着没有__dict__),但可以用__getstate__。有些物体也可能被注册具有用于酸洗的自定义功能。因此,您需要知道这种情况是否也发生过。

从技术上讲,您可以在 Python 中实现一个函数来检查所有这些,但相比之下,它会相当慢。最简单的(也可能是性能最好的,如pickle is 用C实现)方法是简单地尝试腌制您想要检查的对象。

我用 PyCharm 对各种东西进行了测试...它不会用这种方法停止。关键是您必须预见到几乎所有类型的异常(请参阅脚注3在文档中)。警告是可选的,它们主要是对该问题的上下文的解释。

def is_picklable(obj: Any) -> bool:
    try:
        pickle.dumps(obj)
        return True
    except (pickle.PicklingError, pickle.PickleError, AttributeError, ImportError):
        # https://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickled
        return False
    except RecursionError:
        warnings.warn(
            f"Could not determine if object of type {type(obj)!r} is picklable"
            "due to a RecursionError that was supressed. "
            "Setting a higher recursion limit MAY allow this object to be pickled"
        )
        return False
    except Exception as e:
        # https://docs.python.org/3/library/pickle.html#id9
        warnings.warn(
            f"An error occurred while attempting to pickle"
            f"object of type {type(obj)!r}. Assuming it's unpicklable. The exception was {e}"
        )
        return False

使用我上面链接的其他答案中的示例,您可以通过实现来使您的对象可腌制__getstate__ and __setstate__(或子类化并添加它们,或制作包装类)调整您的make_args_pickable...

class Unpicklable:
    """
    A simple marker class so we can distinguish when a deserialized object
    is a string because it was originally unpicklable 
    (and not simply a string to begin with)
    """
    def __init__(self, obj_str: str):
        self.obj_str = obj_str

    def __str__(self):
        return self.obj_str

    def __repr__(self):
        return f'Unpicklable(obj_str={self.obj_str!r})'


class PicklableNamespace(Namespace):
    def __getstate__(self):
        """For serialization"""

        # always make a copy so you don't accidentally modify state
        state = self.__dict__.copy()

        # Any unpicklables will be converted to a ``Unpicklable`` object 
        # with its str format stored in the object
        for key, val in state.items():
            if not is_picklable(val):
                state[key] = Unpicklable(str(val))
        return state
    def __setstate__(self, state):
        self.__dict__.update(state)  # or leave unimplemented

在实际操作中,我将腌制一个属性包含文件句柄(通常不可腌制)的名称空间,然后加载腌制数据。

# Normally file handles are not picklable
p = PicklableNamespace(f=open('test.txt'))

data = pickle.dumps(p)
del p

loaded_p = pickle.loads(data)
# PicklableNamespace(f=Unpicklable(obj_str="<_io.TextIOWrapper name='test.txt' mode='r' encoding='cp1252'>"))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使具有不可选取字段的对象可选取的正确方法是什么? 的相关文章

  • 使用 Python 编辑 RTF 文件

    也许这是一个愚蠢的问题 但我不明白 所以道歉 我有一个 RTF 文档 我想更改它 例如 有一个表 我想复制一行并以面向对象的方式更改代码中第二行中的文本 我认为 pyparsing 应该是可行的方法 但我摆弄了几个小时但没有明白 我没有提供
  • 通过 boto3 承担 IAM 用户角色时访问被拒绝

    Issue 我有一个 IAM 用户和一个 IAM 角色 我正在尝试将 IAM 用户配置为有权使用 STS 承担 IAM 角色 我不确定为什么收到 访问被拒绝 错误 Details IAM 角色 arn aws iam 123456789 r
  • 将 yerr/xerr 绘制为阴影区域而不是误差线

    在 matplotlib 中 如何将误差绘制为阴影区域而不是误差条 例如 而不是 忽略示例图中各点之间的平滑插值 这需要进行一些手动插值 或者只是获得更高分辨率的数据 您可以使用pyplot fill between https matpl
  • 如何在python中附加两个字节?

    说你有b x04 and b x00 你如何将它们组合起来b x0400 使用Python 3 gt gt gt a b x04 gt gt gt b b x00 gt gt gt a b b x04 x00
  • Python re无限执行

    我正在尝试执行这段代码 import re pattern r w w s re compiled re compile pattern results re compiled search COPRO HORIZON 2000 HOR p
  • 将 C++ 指针作为参数传递给 Cython 函数

    cdef extern from Foo h cdef cppclass Bar pass cdef class PyClass cdef Bar bar def cinit self Bar b bar b 这总是会给我类似的东西 Can
  • 使用 Python 3 动态插入到 sqlite

    我想使用 sqlite 写入多个表 但我不想提前手动指定查询 有数十种可能的排列 例如 def insert sqlite tablename data list global dbc dbc execute insert into tab
  • OpenCV 跟踪器:模型未在函数 init 中初始化

    在视频的第一帧 我运行一个对象检测器 它返回对象的边界框 如下所示
  • 如何使用 opencv python 计算乐高积木上的孔数?

    我正在开发我的 python 项目 我需要计算每个乐高积木组件中有多少个孔 我将从输入 json 文件中获取有关需要计算哪个程序集的信息 如下所示 img 001 red 0 blue 2 white 1 grey 1 yellow 1 r
  • 在Python中读取tiff标签

    我正在尝试用 Python 读取 tiff 文件的标签 该文件是 RGB 的uint16每个通道的值 我目前正在使用tifffile import tifffile img tifffile imread file tif 然而 img是一
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • 如何在 Django Rest 框架中编写“删除”操作的测试

    我正在为 Django Rest Framework API 编写测试 我一直在测试 删除 我对 创建 的测试工作正常 这是我的测试代码 import json from django urls import reverse from re
  • 检索 geodjango 多边形对象的边界框

    如何在 geodjango 中获取 MultiPolygon 对象的边界框 在 API 中找不到任何内容http geodjango org docs geos html http geodjango org docs geos html
  • 使用seaborn绘制简单线图

    我正在尝试使用seaborn python 绘制ROC曲线 对于 matplotlib 我只需使用该函数plot plt plot one minus specificity sensitivity bs where one minus s
  • 基于值而不是类型的单次调度

    我在 Django 上构建 SPA 并且有一个庞大的功能 其中包含许多功能if用于检查我的对象字段的状态名称的语句 像这样 if self state new do some logic if self state archive do s
  • PyInstaller“ValueError:源代码字符串不能包含空字节”

    我得到了一个ValueError source code string cannot contain null bytes执行命令时pyinstaller main py在具有和不具有管理员权限的cmd中 Traceback most re
  • 寻找完美的正方形

    我有这个Python代码 def sqrt x ans 0 if x gt 0 while ans ans lt x ans ans 1 if ans ans x print x is not a perfect square return
  • 高效创建抗锯齿圆形蒙版

    我正在尝试创建抗锯齿 加权而不是布尔 圆形掩模 以制作用于卷积的圆形内核 radius 3 no of pixels to be 1 on either side of the center pixel shall be decimal a
  • 如何在 scikit 中加载 CSV 数据并将其用于朴素贝叶斯分类

    尝试加载自定义数据以在 Scikit 中执行 NB 分类 需要帮助将示例数据加载到 Scikit 中 然后执行 NB 如何加载目标的分类值 使用相同的数据进行训练和测试 或使用完整的数据集进行测试 Sl No Member ID Membe
  • 使用 paramiko 运行 Sudo 命令

    我正在尝试执行sudo使用 python paramiko 在远程计算机上运行命令 我尝试了这段代码 import paramiko ssh paramiko SSHClient ssh set missing host key polic

随机推荐

  • node.nextSibling 和 ChildNode.nextElementSibling 之间有什么区别?

    div Here is div 01 div div Here is div 02 div 它们不是同一件事吗 两者都返回紧随其后的节点 我读了很多文章 但在我看来都喜欢同样的东西 但不知道在哪里使用其中一个与另一个 nextElement
  • Bootstrap 方法返回 null - Android 在启动时立即崩溃

    React Native 和 React native navigation 的新手 应用程序在 iOS 上运行正常 但在启动时很快抛出以下异常 E AndroidRuntime FATAL EXCEPTION main Process c
  • Apache 反向代理到节点 - 连接被拒绝:AH00957

    我正在尝试让一个全新的基于云的服务器与默认版本的 20 04 服务器 ubuntu 一起使用 apache 和节点 节点服务器似乎正在运行 没有报告 4006 端口已打开的问题 但我相信我的 apache 配置不是 该请求将挂起很长一段时间
  • Flash Builder 中的输出文件名

    我是第一次尝试 Flash Builder 但我陷入了一个简单的任务 如何更改输出文件名 默认情况下 Flash Builder 为 SWF 提供与入口点类相同的名称 但我找不到任何地方可以更改它 Anybody 只需在编译和构建时更改主应
  • 在 Java 线程中模拟竞争条件的代码

    我是 Java 多线程新手 我正在学习竞争条件的概念 基于Oracle文档 http docs oracle com javase tutorial essential concurrency interfere html 我创建了一个示例
  • 使用 mapstruct 将 null 设置为 target

    我正在使用 mapstruct 我想知道是否有任何方法可以为某些目标属性设置 null 值 例如 public class MySource private String prop1 private String prop2 public
  • 使用 Openxml 2.0 在 Excel 中获取单元格背景颜色

    我正在尝试获取 Excel 电子表格中单元格的背景颜色 我正在使用 Open XML 2 0 SDK 我可以打开 xlsx 文件并获取单元格值 我获取背景颜色的代码如下 public BackgroundColor GetCellBackC
  • 设置 Gradle 缓存目录?

    是否可以设置 Gradle 缓存目录 而无需设置 GRADLE USER HOME 环境变量 我希望 Gradle 缓存与我的代码存在于同一工作区中 但这似乎只有通过围绕 Gradle 的 bash 脚本才能实现 为了澄清起见 我正在讨论包
  • Svc 处理程序到 SMC 调用

    如何用C编写svc处理程序来调用SMC 监视模式 指令以切换到arm cortex a9的监视模式 即从管理模式到监视模式需要在 svc 处理程序中完成哪些操作 如何在 C 中编写相同的内容 详细的答案值得赞赏 示例可以在 Linux 源代
  • 在 Python 中初始化 2D 列表:如何对每一行进行深拷贝?

    假设我想初始化一个全为 0 的 2D Python 列表 我会这样做 test 0 0 10 10 然后我开始修改第一个列表中的值 test 0 0 1 0 但这会由于某种原因影响所有列表的第一项 print test 1 0 0 0 0
  • 检测文本溢出已起作用并添加包含全文的工具提示

    我有一个包含电子邮件地址的简单跨度 span email protected span 在我的 CSS 中 跨度设置为固定宽度并带有省略号溢出 email display inline block width 100px overflow
  • maven支持kapt吗?

    是否可以在基于 Maven 的项目中运行 kapt kotlin 注释处理 如果是 我如何将 kapt 集成到 Maven 构建系统中 自 Kotlin 1 1 2 起 现在支持 Gradle 和 Maven 来运行 KAPT 插件 这记录
  • 无法通过引用传递参数 2 - uuid PDO

    我正在尝试插入UUID 和我的INSERT query handle gt beginTransaction Define query query INSERT INTO users users uuid type id VALUES uu
  • if-else-if 阶梯的两个部分的条件语句均为 true

    如果你有这样的代码 if A gt X B gt Y Action1 else if A gt X B gt Y Action2 With A gt X and B gt Y 将两个部分if else if梯子被执行 我正在处理存在此问题的
  • 多彩多姿的占位符文本

    我需要创建一个具有彩色占位符文本的 HTML 文本输入元素 所有文本都应为灰色 但结束星号应为红色 如下所示 在我看来 这是一项看似简单的任务 但实际上要复杂得多 因为浏览器限制了我们设置本机输入元素样式的能力 我听说有人使用 CSS 来覆
  • 什么是应用程序之间的本机消息传递以及它如何工作?

    Chrome 开发者文档提到了一个叫做Native Messaging直接从 Chrome 扩展程序或应用程序与其他桌面应用程序进行通信 我如何判断桌面应用程序何时具有此类可用的本机消息传递以及它可以接受哪种类型的通信 有没有办法让应用程序
  • documentdb 模拟器 gatewayservice 在启动时崩溃

    我想了解 documentdb 并安装模拟器 看起来没有错误 但是 启动后我的服务崩溃了 网关服务启动 从标题来看 我猜测这是模拟器的一项重要服务 有趣的是 模拟器似乎继 续加载并尝试打开 https localhost 8081 expl
  • 如何将答案转换为小数点后两位

    这是我的代码 我想要的输出是txtA Text and txtB Text保留两位小数 Public Class Form1 Private Sub btncalc Click ByVal sender As System Object B
  • 为什么 EF 5.x 对表使用复数名称?

    我对 ORM 框架 例如 Hibernate 甚至 Entity Framework 3 0 有一些经验 默认情况下 这些框架使用表的单数名称 例如 类 User 将映射到表 User 但是 当我使用 Visual Studio 2012
  • 使具有不可选取字段的对象可选取的正确方法是什么?

    对我来说 我所做的就是检测不可选取的内容并将其放入字符串中 我想我也可以将其删除 但随后它会错误地告诉我该字段不存在 但我宁愿让它存在但成为字符串 但我想知道是否有一种不那么老套 更正式的方式来做到这一点 我当前使用的代码 def make