您可以__slots__使用列表或元组(或任何可迭代的?)在新型python类中进行定义。创建实例后,该类型仍然存在。
鉴于元组总是比列表更有效率并且是不变的,是否有任何理由不希望使用元组__slots__呢?
>>> class foo(object):
... __slots__ = ('a',)
...
>>> class foo2(object):
... __slots__ = ['a']
...
>>> foo().__slots__
('a',)
>>> foo2().__slots__
['a']
Run Code Online (Sandbox Code Playgroud)
首先,元组没有比列表更有效;它们都支持与C API代码完全相同的快速迭代机制,并且使用相同的代码从Python进行索引和迭代。
更重要的是,除了在构造过程中,该__slots__机制实际上并不使用该__slots__成员。文档可能没有对此进行清楚的解释,但是如果您仔细阅读了所有要点,则信息就足够了。
实际上,它必须是真实的。否则,这将行不通:
class Foo(object):
__slots__ = (x for x in ['a', 'b', 'c'] if x != 'b')
Run Code Online (Sandbox Code Playgroud)
……更糟糕的是:
slots = ['a', 'b', 'c']
class Foo(object):
__slots__ = slots
foo = Foo()
slots.append('d')
foo.d = 4
Run Code Online (Sandbox Code Playgroud)
为了进一步证明:
>>> a = ['a', 'b']
>>> class Foo(object):
... __slots__ = a
>>> del Foo.__slots__
>>> foo = Foo()
>>> foo.d = 3
AttributeError: 'Foo' object has no attribute 'd'
>>> foo.__dict__
AttributeError: 'Foo' object has no attribute '__dict__'
>>> foo.__slots__
AttributeError: 'Foo' object has no attribute '__slots__'
Run Code Online (Sandbox Code Playgroud)
因此,该__slots__成员Foo实际上仅是出于文档和自省的目的。这意味着不存在性能问题或行为问题,仅是一种样式问题。
根据Python文档..
可以为此类变量分配一个字符串、可迭代对象或带有实例使用的变量名称的字符串序列。
因此,您可以使用任何可迭代对象来定义它。您使用哪一个取决于您,但就“首选”而言,我会使用一个列表。
首先,让我们看看如果性能不是问题的话,什么是首选,这意味着您在所有 Python 代码中在列表和元组之间做出的决定都是相同的。我会说一个列表,原因是因为元组被设计为具有语义结构:它在语义上应该意味着您将元素存储为第一项而不是第二项。例如,如果您将 (X,Y) 坐标元组(X)的第一个值存储为第二项,则您完全改变了结构的语义值。如果重新排列列表中属性的名称__slots__,则在语义上没有更改任何内容。因此,在这种情况下,您应该使用列表。
现在,关于性能。首先,这可能是不成熟的优化。我不知道列表和元组之间的性能差异,但我猜无论如何都不会有。但即使假设存在,它实际上也只有在__slots__变量被多次访问时才会发挥作用。
我实际上并没有查看何时访问的代码__slots__,但我运行了以下测试。
print('Defining slotter..')
class Slotter(object):
def __iter__(self):
print('Looking for slots')
yield 'A'
yield 'B'
yield 'C'
print('Defining Mine..')
class Mine(object):
__slots__ = Slotter()
print('Creating first mine...')
m1 = Mine()
m1.A = 1
m1.B = 2
print('Creating second mine...')
m2 = Mine()
m2.A = 1
m2.C = 2
Run Code Online (Sandbox Code Playgroud)
基本上,我使用自定义类,以便我可以准确地看到插槽变量何时实际迭代。您将看到,当定义类时,它只完成一次。
Defining slotter..
Defining Mine..
Looking for slots
Creating first mine...
Creating second mine...
Run Code Online (Sandbox Code Playgroud)
除非我错过了再次迭代变量的情况__slots__,否则我认为最坏的情况下性能差异可以忽略不计。
| 归档时间: |
|
| 查看次数: |
1280 次 |
| 最近记录: |