//........
//.........
root.setPadding(new Insets(15));
root.setTop(menuBar);
//root.setCenter(hbox);
Scene scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
stage.setTitle("Dummy Title");
stage.setScene(scene);
stage.show();
//........
//.........
生成小于“普通”类的实例。这是为什么?
答案 0 :(得分:8)
对我来说,看起来节省的内存来自实例上缺少__weakref__
。
所以如果我们有:
class Spam1(object):
__slots__ = ('__dict__',)
class Spam2(object):
__slots__ = ('__dict__', '__weakref__')
class Spam3(object):
__slots__ = ('foo',)
class Eggs(object):
pass
objs = Spam1(), Spam2(), Spam3(), Eggs()
for obj in objs:
obj.foo = 'bar'
import sys
for obj in objs:
print(type(obj).__name__, sys.getsizeof(obj))
结果(在python 3.5.2上)是:
Spam1 48
Spam2 56
Spam3 48
Eggs 56
我们发现Spam2
(__weakref__
)与Eggs
(传统类)的大小相同。
请注意,通常情况下,这种节省将是完全无关紧要的(并且阻止您在启用插槽的类中使用弱引用)。通常,__slots__
的节省来自于他们首先不创建__dict__
这一事实。由于__dict__
是使用一个有点稀疏的表实现的(为了帮助避免哈希冲突并维护O(1)查找/插入/删除),因此每个字典都有相当多的空间用于你的程序创建。如果您将'__dict__'
添加到__slots__
,则会错过此优化(仍然会创建一个dict)。
为了更多地探讨这个问题,我们可以添加更多插槽:
class Spam3(object):
__slots__ = ('foo', 'bar')
现在,如果我们重新运行,我们会看到它需要:
Spam1 48
Spam2 56
Spam3 56
Eggs 56
因此每个插槽在实例上占用8个字节(对我来说 - 可能因为我的系统上有8个字节sizeof(pointer)
)。另请注意,__slots__
是通过创建描述符(它们位于类而非实例)来实现的。因此,实例(即使您可能会发现通过__slots__
列出的dir(instance)
)实际上并未携带__slots__
值 - 这是由类< / em>的
这也会导致您的插槽启用类无法设置“默认”值...例如以下代码不起作用:
class Foo(object):
__slots__ = ('foo',)
foo = 'bar'
所以要把它煮熟:
__slots__ = ('__dict__',)
__dict__
广告位且在实例上创建了__weakref__
广告__slots__ = ('__dict__',)
创建了__dict__
个插槽,但未在该实例上创建__weakref__
个插槽。__slots__
实际上都不会放在实例上。它存在于类中(即使您可能会从dir(instance)
看到它。)__slots__
所获得的节省可能是微不足道的。如果您没有为实例创建__slots__
,则会发生dict
的实际节省(因为dict
占用的内存多于其内容所需的存储总和,因为包装有些稀疏数据结构中的数据)。最重要的是,以这种方式使用插槽存在缺点(例如,没有对您的实例的弱引用)。