__slots__
Python中的目的是什么- 特别是关于我何时想要使用它,何时不想使用它?
在插槽上的Python数据模型参考部分中,有一个使用说明列表__slots__
.我对第1和第6项完全感到困惑,因为它们似乎相互矛盾.
第一项:
__slots__
的__dict__
属性将始终可访问,因此__slots__
子类中的定义毫无意义.第六项:
__slots__
声明限制为定义它的类.因此,子类将具有一个,__dict__
除非它们也定义__slots__
(它必须只包含任何其他槽的名称).在我看来,这些项目可以更好地措辞或通过代码显示,但我一直试图绕过这个,我仍然感到困惑.我不明白怎么__slots__
都应该被使用,而我试图让他们的工作更好地把握.
问题:
有人可以用简单的语言向我解释在子类化时继承槽的条件是什么?
(简单的代码示例会有所帮助,但不是必需的.)
我正在尝试挑选我定义的(新式)类的对象.但是我收到以下错误:
>>> with open('temp/connection.pickle','w') as f:
... pickle.dump(c,f)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/usr/lib/python2.5/pickle.py", line 1362, in dump
Pickler(file, protocol).dump(obj)
File "/usr/lib/python2.5/pickle.py", line 224, in dump
self.save(obj)
File "/usr/lib/python2.5/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/usr/lib/python2.5/pickle.py", line 419, in save_reduce
save(state)
File "/usr/lib/python2.5/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.5/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/usr/lib/python2.5/pickle.py", line 663, in _batch_setitems
save(v)
File …
Run Code Online (Sandbox Code Playgroud) 我正在使用程序上的小波,我使用该程序包wavelets
使用该函数创建时间序列的DWT dwt
.该函数返回类的对象dwt
,这与许多时隙的S4对象:W
,V
,levels
,filter
,等.
如何W
作为向量访问?
最近Python中的某种情况让我感到震惊,经过一番研究后,其原因仍然不完全清楚.以下类定义似乎完美无缺,并将产生预期的内容:
class A: __slots__ = 'a', 'b'
class B(A): __slots__ = ()
class C(A): __slots__ = ()
class D(B, C): __slots__ = ()
Run Code Online (Sandbox Code Playgroud)
这些是以钻石继承模式排列的四个类.但是,不允许有些类似的模式.以下类定义看起来好像它们的功能与第一个相同:
class B: __slots__ = 'a', 'b'
class C: __slots__ = 'a', 'b'
class D(B, C): __slots__ = ()
Traceback (most recent call last):
File "<pyshell#74>", line 1, in <module>
class D(B, C): __slots__ = ()
TypeError: multiple bases have instance lay-out conflict
Run Code Online (Sandbox Code Playgroud)
但是,TypeError
在此示例中引发了a .因此出现了三个问题:(1)考虑到插槽名称,这是Python中的错误吗?(2)这样的答案有什么理由?(3)最好的解决方法是什么?
参考文献:
MCVE
https://github.com/hyperbotauthor/minvue3cliapp
MCVE 直播
https://codesandbox.io/s/white-browser-fl7ji
我有一个 Vue 3 cli-service 应用程序,它使用带有插槽的组合 API 组件。
该HelloWorld
组件渲染它在 a 中接收到的槽div
:
// src/components/Helloworld.js
import { defineComponent, h } from "vue";
export default defineComponent({
setup(props, { slots }) {
return () => h("div", {}, slots);
}
});
Run Code Online (Sandbox Code Playgroud)
该组件在其功能中Composite
使用并填充其槽:HelloWorld
setup
// src/components/Composite.js
import { defineComponent, h } from "vue";
import HelloWorld from "./HelloWorld";
export default defineComponent({
setup(props, { slots }) {
return () =>
h(HelloWorld, {}, [h("div", {}, ["Div 1"]), h("div", …
Run Code Online (Sandbox Code Playgroud) 我有一棵拥有数十万个节点的大树,我正在使用它__slots__
来减少内存消耗.我刚刚发现了一个非常奇怪的错误并修复了它,但我不明白我看到的行为.
这是一个简化的代码示例:
class NodeBase(object):
__slots__ = ["name"]
def __init__(self, name):
self.name = name
class NodeTypeA(NodeBase):
name = "Brian"
__slots__ = ["foo"]
Run Code Online (Sandbox Code Playgroud)
然后我执行以下操作:
>>> node = NodeTypeA("Monty")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
AttributeError: 'NodeTypeA' object attribute 'name' is read-only
Run Code Online (Sandbox Code Playgroud)
如果NodeTypeA.name
没有定义则没有错误(旁注:该属性是错误的,没有理由在那里).如果NodeTypeA.__slots__
从未定义过也没有错误,因此它有一个__dict__
.
我不明白的是:为什么超类中存在类变量会干扰在子类的槽中设置实例变量?
任何人都可以解释为什么这种组合导致object attribute is read-only
错误?我知道我的例子是人为的,并且不太可能是真实程序中的故意,但这并不会使这种行为变得不那么奇怪.
谢谢,
乔纳森
我需要使用None初始化实例的所有插槽.如何获取派生类的所有插槽?
示例(不起作用):
class A(object):
__slots__ = "a"
def __init__(self):
# this does not work for inherited classes
for slot in type(self).__slots__:
setattr(self, slot, None)
class B(A):
__slots__ = "b"
Run Code Online (Sandbox Code Playgroud)
我可以使用一个额外的class属性来保存所有类的槽(包括继承的),比如
class A(object):
__slots__ = "a"
all_slots = "a"
def __init__(self):
# this does not work for inherited classes
for slot in type(self).all_slots:
setattr(self, slot, None)
class B(A):
__slots__ = "b"
all_slots = ["a", "b"]
Run Code Online (Sandbox Code Playgroud)
但这似乎不是最理想的.
任何评论表示赞赏!
干杯,
一月
经过Mark Shannon对Python对象的优化,普通对象和带槽的对象有什么不同吗?据我所知,在正常用例中进行此优化后,对象没有字典。新的 Python 对象是否已经完全不需要使用槽了?
我听说__slots__
通过避免字典查找使对象更快.我的困惑来自于Python是一种动态语言.在静态语言中,我们a.test
通过执行编译时优化来避免字典查找,以便在我们运行的指令中保存索引.
现在,在Python中,a
可以很容易地成为另一个具有字典或不同属性集的对象.看起来我们仍然需要进行字典查找 - 唯一的区别似乎是我们只需要一个类的字典,而不是每个对象的字典.
有了这个理性,
__slots__
避免字典查找?