Note that there are some explanatory texts on larger screens.

plurals
  1. POIs it possible to add __slots__ in decorator of class that already defines __slots__?
    primarykey
    data
    text
    <p>Let me start off by saying that I understand how slots and metaclasses work in Python. Playing around with the two, I've run into an interesting problem. Here's a minimal example:</p> <pre><code>def decorator(cls): dct = dict(cls.__dict__) dct['__slots__'] = ('y',) return type('NewClass', cls.__bases__, dct) @decorator class A(object): __slots__= ('x',) def __init__(self): self.x = 'xx' A() </code></pre> <p>This produces the following exception:</p> <pre><code>Traceback (most recent call last): File "p.py", line 12, in &lt;module&gt; A() File "p.py", line 10, in __init__ self.x = 'xx' TypeError: descriptor 'x' for 'A' objects doesn't apply to 'NewClass' object </code></pre> <p>Now, I know why this happens: the descriptor created for the slot <code>x</code> must be able to reference the reserved space for the slot. Only instances of class A, or instances of subclasses of A, have this reserved space, and therefore only those instances can use the descriptor <code>x</code>. In the above example, the metaclass creates a new type that is a sublcass of A's base classes, but not of A itself, so we get the exception. Simple enough.</p> <p>Of course, in this simple example, either of the following two definitions of <code>decorator</code> will work around the problem:</p> <pre><code>def decorator(cls): dct = dict(cls.__dict__) dct['__slots__'] = ('y',) return type('NewClass', (cls,) + cls.__bases__, dct) def decorator(cls): class NewClass(cls): __slots__ = ('y',) return NewClass </code></pre> <p>But these work-arounds aren't exactly he same as the original, as they both add A as a base class. They can fail in a more complicated set up. For example, if the inheritance tree is more complicated, you might run into the following exception: <code>TypeError: multiple bases have instance lay-out conflict</code>.</p> <p>So my very specific question is: </p> <p>Is there are way to create a new class, via a call to <code>type</code>, that modifies the <code>__slots__</code> attribute of an existing class, but does not add the existing class as a base class of the new class?</p> <p>Edit:</p> <p>I know that strict metaclasses are another work around for my examples above. There are lots of ways to to make the minimal examples work, but my question is about creating a class via <code>new</code> that is based on an existing class, not about how to make the examples work. Sorry for the confusion.</p> <p>Edit 2:</p> <p>Discussion in the comments has led me a more precise question than what I originally asked:</p> <p><strong>Is it possible to create a class, via a call to <code>type</code>, that uses the slots and descriptors of an existing class without being a descendant of that class?</strong></p> <p>If the answer is "no", I'd appreciate a source as to why not.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload