当被属性遮蔽时修改类 __dict__

2023-11-25

我正在尝试修改类中的值__dict__直接使用类似的东西X.__dict__['x'] += 1。不可能进行这样的修改,因为一个类__dict__实际上是一个mappingproxy不允许直接修改值的对象。尝试直接修改或等效的原因是我试图将类属性隐藏在元类上定义的同名属性后面。这是一个例子:

class Meta(type):
    def __new__(cls, name, bases, attrs, **kwargs):
        attrs['x'] = 0
        return super().__new__(cls, name, bases, attrs)
    @property
    def x(cls):
        return cls.__dict__['x']

class Class(metaclass=Meta):
    def __init__(self):
        self.id = __class__.x
        __class__.__dict__['x'] += 1

此示例显示了为每个实例创建自动递增 ID 的方案Class。线路__class__.__dict__['x'] += 1不能被取代setattr(__class__, 'x', __class__.x + 1)因为x is a property没有二传手Meta。它只会改变一个TypeError from mappingproxy进入一个AttributeError from property.

我试过搞乱__prepare__,但这没有效果。实施于type已经返回一个可变的dict对于命名空间。不变的mappingproxy似乎已经陷入type.__new__,我不知道如何避免。

我也尝试过重新绑定整个__dict__引用可变版本,但也失败了:https://ideone.com/w3HqNf,这意味着也许mappingproxy不是创建于type.__new__.

我如何修改一个类dict直接值,即使被元类属性遮蔽?虽然它may实际上是不可能的,setattr能够以某种方式做到这一点,所以我希望有一个解决方案。

我的主要要求是有一个看起来只读的类属性,并且不在任何地方使用其他名称。我并不完全沉迷于使用元类的想法property与同名班级dict条目,但这通常是我在常规实例中隐藏只读值的方式。

EDIT

我终于知道班级在哪里了__dict__变得不可变。它在最后一段中有描述“创建类对象”的部分数据模型参考:

当一个新类被创建时type.__new__,作为名称空间参数提供的对象将被复制到新的有序映射,并丢弃原始对象。新副本包装在只读代理中,该代理成为__dict__类对象的属性。


也许最好的方法是:选择另一个名字。致电物业x和字典键'_x',这样您就可以以正常方式访问它。

替代方法:添加另一层间接:

class Meta(type):
    def __new__(cls, name, bases, attrs, **kwargs):
        attrs['x'] = [0]
        return super().__new__(cls, name, bases, attrs)
    @property
    def x(cls):
        return cls.__dict__['x'][0]

class Class(metaclass=Meta):
    def __init__(self):
        self.id = __class__.x
        __class__.__dict__['x'][0] += 1

这样你就不必修改类字典中的实际条目。

超级黑客的方式可能会彻底导致你的Python出现段错误:通过访问底层字典gc module.

import gc

class Meta(type):
    def __new__(cls, name, bases, attrs, **kwargs):
        attrs['x'] = 0
        return super().__new__(cls, name, bases, attrs)
    @property
    def x(cls):
        return cls.__dict__['x']

class Class(metaclass=Meta):
    def __init__(self):
        self.id = __class__.x
        gc.get_referents(__class__.__dict__)[0]['x'] += 1

这绕过了关键工作type.__setattr__确实可以维护内部不变量,特别是在 CPython 的类型属性缓存等方面。这是一个糟糕的想法,我只是提到它,这样我就可以把这个警告放在这里,因为如果其他人提出这个想法,他们可能不知道弄乱底层字典是非常危险的。

这样做很容易导致悬空引用,而且我在尝试这样做时已经多次出现 Python 段错误。这是一个简单的案例在 Ideone 上崩溃:

import gc

class Foo(object):
    x = []

Foo().x
gc.get_referents(Foo.__dict__)[0]['x'] = []

print(Foo().x)

Output:

*** Error in `python3': double free or corruption (fasttop): 0x000055d69f59b110 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bcb)[0x2b32d5977bcb]
/lib/x86_64-linux-gnu/libc.so.6(+0x76f96)[0x2b32d597df96]
/lib/x86_64-linux-gnu/libc.so.6(+0x7778e)[0x2b32d597e78e]
python3(+0x2011f5)[0x55d69f02d1f5]
python3(+0x6be7a)[0x55d69ee97e7a]
python3(PyCFunction_Call+0xd1)[0x55d69efec761]
python3(PyObject_Call+0x47)[0x55d69f035647]
... [it continues like that for a while]

And 这是一个案例结果错误,并且没有嘈杂的错误消息来提醒您出现问题的事实:

import gc

class Foo(object):
    x = 'foo'

print(Foo().x)

gc.get_referents(Foo.__dict__)[0]['x'] = 'bar'

print(Foo().x)

Output:

foo
foo

我绝对不保证任何安全的使用方式,即使事情恰好在一个 Python 版本上运行,它们也可能无法在未来的版本上运行。摆弄它可能很有趣,但它并不是真正可以使用的东西。说真的,不要这样做。你want向你的老板解释你的网站瘫痪了,或者你发布的数据分析需要被撤回,因为你接受了这个坏主意并使用了它?

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

当被属性遮蔽时修改类 __dict__ 的相关文章

  • Python Nose 导入错误

    我似乎无法理解鼻子测试框架 https nose readthedocs org en latest 识别文件结构中测试脚本下方的模块 我已经设置了演示该问题的最简单的示例 下面我会解释一下 这是包文件结构 init py foo py t
  • DataFrame 在函数内部修改

    我面临一个我以前从未观察到的函数内数据帧修改的问题 有没有一种方法可以处理这个问题 以便初始数据帧不被修改 def test df df tt np nan return df dff pd DataFrame data 现在 当我打印时d
  • Python:记录垃圾收集器

    我有一个 python 应用程序 有一些性能问题 我想将垃圾收集器的事件 特别是何时调用 添加到我的日志中 是否可以 thanks http docs python org library gc html gc set debug http
  • 子进程改变目录

    我想在子目录 超级目录中执行脚本 我需要首先进入该子目录 超级目录 我无法得到subprocess进入我的子目录 tducin localhost Projekty tests ve python Python 2 7 4 default
  • Python 遍历目录树的方法是什么?

    我觉得分配文件和文件夹并执行 item 部分有点黑客 有什么建议么 我正在使用Python 3 2 from os import from os path import def dir contents path contents list
  • Python,将迭代函数变成递归函数

    我创建了一个输出 4 3 2 1 0 1 2 3 4 的迭代函数 def bounce2 n s n for i in range n print n n n 1 if n lt 0 for i in range s 1 print n n
  • Python sqlite3游标没有属性commit

    当我运行这段代码时 path Scripts wallpapers single png conn sqlite3 connect Users Heaven Library Application Support Dock desktopp
  • 如何找到列表S的所有分区为k个子集(可以为空)?

    我有一个唯一元素列表 比方说 1 2 我想将其拆分为 k 2 个子列表 现在我想要所有可能的子列表 1 2 1 2 2 1 1 2 我想分成 1 1 2 我怎样才能用 Python 3 做到这一点 更新 我的目标是获取 N 个唯一数字列表的
  • Pyspark 数据框逐行空列列表

    我有一个 Spark 数据框 我想创建一个新列 其中包含每行中具有 null 的列名称 例如 原始数据框是 col 1 col 2 col 3 62 45 null 62 49 56 45 null null null null null
  • Python 正则表达式部分匹配或“hitEnd”

    我正在编写一个扫描器 因此我将任意字符串与正则表达式规则列表进行匹配 如果我可以模拟 Java hitEnd 功能 不仅知道正则表达式何时不匹配 还知道何时匹配 这将非常有用 can t匹配 当正则表达式匹配器在决定拒绝输入之前到达输入末尾
  • 如何使用循环将十进制转换为二进制?

    我想编写一个程序 将十进制数 0 到 9 转换为二进制数 我可以编写如何使用重复除法将十进制数转换为二进制数的代码 但是 我在创建一个以二进制格式打印十进制数字 0 到 9 的循环时遇到了麻烦 这是我的代码 number 0 remaind
  • str.translate 给出 TypeError - Translate 采用一个参数(给定 2 个参数),在 Python 2 中工作

    我有以下代码 import nltk os json csv string cPickle from scipy stats import scoreatpercentile lmtzr nltk stem wordnet WordNetL
  • 如何对这个 Flask 应用程序进行单元测试?

    我有一个 Flask 应用程序 它使用 Flask Restless 来提供 API 我刚刚写了一些身份验证来检查 如果消费者主机被识别 该请求包含一个哈希值 通过加密 POST 的请求内容和 GET 的 URL 以及秘密 API 密钥来计
  • Django - 电子邮件发送两次

    每当我使用如下所示的电子邮件设置从views py调用下面的方法时 电子邮件的两份副本都会发送给收件人 并且我收到如下所示的错误 def sendEmailBasic request msg EmailMessage Request Cal
  • pip 安装软件包两次

    不幸的是我无法重现它 但我们已经见过几次了 pip 将一个软件包安装两次 如果卸载第一个 第二个就会可见并且也可以被卸载 我的问题 如果一个包安装了两次 如何用 python 检查 背景 我想编写一个测试来检查这一点 devOp Updat
  • 如何检查列表是否为空?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 例如 如果通过以下内容 a 我如何检查是否a是空的 if not a print Lis
  • Django 接受 AM/PM 作为表单输入

    我试图弄清楚如何使用 DateTime 字段在 Django 中接受 am pm 作为时间格式 但我遇到了一些麻烦 我尝试在 forms py 文件中这样设置 pickup date time from DateTimeField inpu
  • 为什么 bot.get_channel() 会产生 NoneType?

    我正在制作一个 Discord 机器人来处理公告命令 当使用该命令时 我希望机器人在特定通道中发送一条消息 并向用户发送一条消息以表明该命令已发送 但是 我无法将消息发送到频道 我尝试了这段代码 import discord import
  • 如何设置 matplotlib 表中列的背景颜色

    我在一个目录中有多个 txt 文件 例如 d memdump 0 txt 1 txt 10 txt 示例文本文件如下 Applications Memory Usage kB Uptime 7857410 Realtime 7857410
  • 获取调用者文件的绝对路径

    假设我在不同的目录中有两个文件 1 py 比如说 在C FIRST FOLDER 1 py and 2 py 比如说 在C SECOND FOLDER 2 py 文件1 py进口2 py using sys path insert 0 pa

随机推荐

  • 使用map对列表元素求和

    我想知道是否可以使用映射来对列表的元素求和 assume a 1 2 3 4 list map sum a 会给出一个错误int object is not iterable因为列表需要可迭代 map sum a 是一个有效的语句 但给定对
  • 渲染不同组件警告时无法更新组件

    我在反应中收到此警告 index js 1 Warning Cannot update a component ConnectFunction while rendering a different component Register T
  • Golang - 扫描某类型的所有结构

    我是 Go 的初学者 我可能认为多年来使用其他语言过于传统 但这就是我想在 Go 中做的事情 假设以下用例 我有接口 I 该接口有函数 start 和 stop 有许多结构体实现该接口 结构体A 结构体B 结构体C 当应用程序启动时 我想在
  • 打印没有行索引和列索引的矩阵

    如果我打印一个矩阵 它会在控制台中显示行索引和列索引 例如 gt print diag 3 1 2 3 1 1 0 0 2 0 1 0 3 0 0 1 如何抑制列索引和行索引 IE 像这样的东西 gt print diag 3 indice
  • 无法获取 hasMany 关联

    我使用了提交eaa1123 余烬 和508479d ember data 构建 JS 文件 我从 Rails 后端返回了以下 JSON 它是使用以下命令生成的active model serializers 0 6 0 posts id 4
  • Django,从 Customer.objects.xxxx 中获取第一个和最后一个元素的最佳、最快方法是什么

    Django 从某些东西中仅获取第一个和最后一个元素的最佳 最快的方法是什么 Customer objects xxxx 这样的过滤器 value list 或 可能是最Pythonic的方式 myset Customer objects
  • 当线程在 Synchronized 块内崩溃时,锁会发生什么情况?

    假设 Thread 1 在对象上同步 synchronize object statement1 statement2 statement3 如果线程 1 在语句 2 上崩溃 对象上的锁会发生什么情况 发生这种情况时 JVM 会自动释放线程
  • 动态加载 css 文件以进行主题化

    我有三个具有不同颜色主题的 css 文件 例如 主题1 css 主题2 css 主题3 css 我想根据所选类别加载它们 是否可以在Angular2中动态加载CSS文件 处理这个问题的正确方法是什么 Thanks 我不确定这是否是正确的方法
  • WCF 服务返回意外响应:(413) 请求实体太大

    我使用 WCF 实现了一小组 REST 服务 其中一项服务接收大量数据 调用它时 这是从 Visual Studio 运行它时 我尚未将其部署到生产服务器 我收到错误 远程服务器返回错误 413 请求实体太大 我的网络配置
  • IntelliJ IDEA 抱怨 @NotNull 参数的 null 检查

    我想在我的项目中使用 Jetbrains Nullable NotNull 注释 我有一个带有 NotNull 字段的类 构造函数自然不接受null但会抛出异常 当然这个构造函数的参数也是用 NotNull 注解的 为什么 IntelliJ
  • 实体框架 4:使用自跟踪实体通过过滤器进行预加载(包含)

    我有一个解决方案 我使用 RTM 模板创建了自我跟踪实体 我已将实体和上下文拆分为两个项目 以便在计划通过 WCF 运行客户端 服务器时可以重用类型定义 我的服务方法之一需要返回 Product 对象的图形 其中子对象为 ProductSk
  • 如何在没有异步/等待的情况下从待解决的承诺中获取数据?

    我有抽象 function fetchDataFromAPI const url https api return fetch url then response gt response json 我想在我的其他代码中使用它 例如 if s
  • 如何在 React Native 中实现“FrameLayout”组件?

    我知道 React Native 中有一个 View 组件 其作用类似于 Android ViewGroup 但它更有可能像 LinearLayout 一样工作 子组件按行或列排列 我想知道如何实现 FrameLayout 行为 子级堆叠在
  • os.fork() 会使用写时复制还是在 Python 中执行父进程的完整复制?

    我想将相当大的数据结构加载到进程中 然后分叉以希望减少总内存消耗 将要os fork以这种方式工作还是复制 Linux RHEL 中的所有父进程 即使使用 COW CPython 也会使用引用计数并将引用计数存储在每个对象的标头中 因此 除
  • mpdf不支持阿拉伯文和中文字体

    我正在使用 mpdf 当我向 WriteHtml 提供阿拉伯语和中文单词时 生成的 pdf 包含方框而不是那些字体 请建议 示例字体 I am testing 我的世界 在 mPDF 6 0 上 我们发现这使得粤语对我们有用 mpdf gt
  • 从独立存储中延迟加载列表框图像

    我有很多图像存储在独立存储中 并希望将它们显示在列表框中 但是 我不希望立即加载所有图像 而是延迟加载 因此 只有当用户滚动查看新项目时 才应加载图像 我还想使用数据绑定来提供列表项的数据和图像 在测试中 我所做的所有图像总是立即立即加载
  • 具有多种内容类型的 ContentChildren

    您好 我目前正在构建一个允许其中包含多种列类型的表 我希望能够像这样使用它
  • 架构arm64的重复符号(Xcode错误)

    我从项目中删除了对 GoogleMobileAdsSDKiOS 7 1 的所有引用 并添加了 7 4 1 当我在模拟器上运行应用程序时 一切正常 但在设备上运行时 我收到 App Mach O 链接器错误 duplicate symbol
  • 从 mysql 字段内的 json 中提取数据

    我有一个包含行的表 其中一行有一个包含如下数据的字段 name Richard lastname null city Olavarria cityId null 我想选择我拥有的所有不同的 城市 值 仅使用mysql服务器 是否可以 我正在
  • 当被属性遮蔽时修改类 __dict__

    我正在尝试修改类中的值 dict 直接使用类似的东西X dict x 1 不可能进行这样的修改 因为一个类 dict 实际上是一个mappingproxy不允许直接修改值的对象 尝试直接修改或等效的原因是我试图将类属性隐藏在元类上定义的同名