- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个类使用 __slots__
并通过覆盖 __setattr__
使它们几乎不可变以始终引发错误:
class A:
__slots__ = ['a', 'b', '_x']
def __init__(self, a, b):
object.__setattr__(self, 'a', a)
object.__setattr__(self, 'b', b)
def __setattr__(self, attr, value):
raise AttributeError('Immutable!')
@property
def x():
return self._x
@x.setter
def x(value):
object.__setattr__(self, '_x', value)
在这里,“私有(private)”属性 _x
是一个占位符,用于与某些自定义硬件交互的复杂操作。
因为 x
是一个属性,我希望能够做类似的事情
inst = A(1, 2)
inst.x = 3
相反,我看到了带有消息 Immutable!
的 AttributeError
。
这里有许多明显的解决方法,例如删除自定义 __setattr__
(我不想这样做)或将其重写为
def __setattr__(self, attr, value):
if attr != 'x':
raise AttributeError('Immutable!')
super().__setattr__(attr, value)
这似乎是一种笨拙的方法,如果我开始添加更多类似的属性,它可能会膨胀得不成比例。
真正的问题是我不明白为什么__slots__
和属性之间没有冲突,但是__setattr__
和属性之间有冲突。查找顺序发生了什么,是否有另一种更优雅的解决方法来解决这个问题?
最佳答案
The real issue is that I do not understand why there is no conflict between
__slots__
and the property, but there is one between__setattr__
and the property.
__slots__
和property
都通过提供 descriptor 来实现属性查找。对于相应的属性。 __slots__
的存在不是通过对 __setattr__
做任何事情来阻止任意实例属性的创建,而是通过阻止创建 __dict__
。 property
和其他描述符不依赖实例 __dict__
,因此它们不受影响。
但是,__setattr__
处理所有 属性赋值,这意味着描述符调用是__setattr__
的责任。如果您的 __setattr__
不处理描述符,则不会处理描述符,并且不会调用 property
setter。
is there another, more elegant workaround to this problem?
你可以明确地只允许属性:
class A:
...
def __setattr__(self, name, value):
if not isinstance(getattr(type(self), name, None), property):
raise AttributeError("Can't assign to attribute " + name)
super().__setattr__(name, value)
或者您可以明确拒绝分配给插槽,并将其他属性分配委托(delegate)给 super().__setattr__
:
class A:
...
def __setattr__(self, name, value):
if isinstance(getattr(type(self), name, None), _SlotDescriptorType):
raise AttributeError("Can't assign to slot " + name)
super().__setattr__(name, value)
# Seems to be the same as types.MemberDescriptorType,
# but the docs don't guarantee it.
_SlotDescriptorType = type(A.a)
关于使用自定义 __setattr__ 和 __slots__ 进行 Python 属性查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46101056/
首先让我说我了解槽和元类在 Python 中的工作方式。玩弄这两个,我遇到了一个有趣的问题。这是一个最小的例子: def decorator(cls): dct = dict(cls.__di
__slots__ 的目的是什么?在 Python 中——尤其是关于我什么时候想使用它,什么时候不想使用它? 最佳答案 In Python, what is the purpose of __slot
我在 Python 的输入系统和 __slots__ 之间有冲突。这是一个可重现的小例子。 from typing import TypeVar, Generic, Sequence T = Type
class Foo(object): __slots__ = ('a',) class Bar(Foo): @property def a(self): ret
我有一节课 __slots__ : class A: __slots__ = ('foo',) 如果我创建一个子类而不指定__slots__,子类将有一个__dict__: class B(A
我正在开发一个需要通过 __init__ 注入(inject)来为其赋予 __dict__ 属性的类,如下所示: class Torrent(Model): def __init__(self
我听说 __slots__ 通过避免字典查找使对象更快。我的困惑来自于 Python 是一种动态语言。在静态语言中,我们通过编译时优化将索引保存在我们运行的指令中,从而避免了对 a.test 的字典查
我需要用 None 初始化一个实例的所有插槽。如何获取派生类的所有插槽? 示例(不起作用): class A(object): __slots__ = "a" def __init__
所以,我正在阅读一些关于 Python 中元类的内容,以及如何使用 type()的三参数 alter-ego 用于动态创建类。但是,第三个参数通常是 dict。初始化要创建的类'__dict__变量。
考虑以下代码: from weakref import ref class Klass(object): # __slots__ = ['foo'] def __init__(self
通过学习《Python类变量和实例变量》一节,了解了如何动态的为单个实例对象添加属性,甚至如果必要的话,还可以为所有的类实例对象统一添加属性(通过给类添加属性)。 那么,Python 是否也允许动态地
早上好 我在尝试在我的一门类(class)中使用 __ 插槽 __ 时遇到问题。我想用它来优化 Classifier 对象的多个实例的创建。我正在使用 Python 3.7.1。 这行得通 class
当我运行这个(2.7.3)时,我得到这个输出: 'Slotted1' object has no attribute 'c' attribute c added to 我不明白 Slotted1 和
最近在学习Python,但是我有一个关于__slots__的问题。我认为是为了限制Class中的参数,同时也限制Class中的方法? 例如: from types import MethodType
最近给 friend 讲解了__slots__的用法。我想向他展示结果并使用了以下代码: import sys class Foo: __slots__ = 'a', 'b' def
我一直在玩弄 __slots__ 并稍微搜索一下,但我仍然对某些细节感到困惑: 我知道 __slots__ 生成某种描述符: >>> class C: ... __slots__ = ('x'
在类中创建结果对象时,是否可以在本例中使用__slots__?我想我可以通过将 '__slots__' 传递到 type 的第三个参数的字典中来让它工作: class GeocodeResult(ob
我读入了Usage of __slots__?在 Python 中使用 __slots__ 实际上可以节省时间。但是,当我尝试使用 datetime 查找所花费的时间时,结果却相反。 import d
我正在使用 Python 3.7 和 Django。我正在阅读 __slots__ .显然,__slots__ 可用于通过提前列出所有对象属性来优化大量此类对象的内存分配。 class MyClass
我正在编写一个配置卷的存储自动化模块。我没有传递在存储 Controller 上实际创建卷所需的六个或更多参数,而是使用 __slots__ 创建了一个参数类,它被传递到 create 方法中,如下所
我是一名优秀的程序员,十分优秀!