<p>在python3中,在使用元类时,它必须准备好,并且它不知道最终(非元)类的基,以便在那时动态地创建一个元类。在</p>
<p>但是,与其让事情复杂化(我承认我无法完全理解您对元类的需求),您可以简单地使用普通的类层次结构,协同使用<code>super</code>作为元类。
你甚至可以用一个简单的
调用<code>type</code>:</p>
<pre><code>class A(type):
def __new__(metacls, name, bases,attrs):
attrs['A'] = "Metaclass A processed"
return super().__new__(metacls, name, bases,attrs)
class B(type):
def __new__(metacls, name, bases,attrs):
attrs['B'] = "Metaclass A processed"
return super().__new__(metacls, name, bases,attrs)
C = type("C", (A, B), {})
class Example(metaclass=C): pass
</code></pre>
<p>以及:</p>
^{pr2}$
<p>如果你的元类一开始就不是为了协作而设计的,那么创建任何自动方法来组合它们是非常困难的——而且可能涉及到在一些元类构造函数中对<code>type.__new__</code>的调用进行monkey修补。在</p>
<p>至于不需要显式地构建<code>C</code>,可以使用一个普通函数作为元类参数,它将检查基并构建一个动态派生元类:</p>
<pre><code>def Auto(name, bases, attrs):
basemetaclasses = []
for base in bases:
metacls = type(base)
if isinstance(metacls, type) and metacls is not type and not metacls in basemetaclasses:
basemetaclasses.append(metacls)
dynamic = type(''.join(b.__name__ for b in basemetaclasses), tuple(basemetaclasses), {})
return dynamic(name, bases, attrs)
</code></pre>
<p>(这段代码与您的代码非常相似-但我使用了三行显式<code>for</code>而不是<code>set</code>以保持元类顺序-这可能很重要)</p>
<p>您可以让它们将Auto作为派生类的元类传递,但在其他情况下,它的工作方式与您的示例相同:</p>
<pre><code>In [61]: class AA(metaclass=A):pass
In [62]: class BB(metaclass=B):pass
In [63]: class CC(AA,BB): pass
-
...
TypeError: metaclass conflict
...
In [66]: class CC(AA,BB, metaclass=Auto): pass
In [67]: type(CC)
Out[67]: __main__.AB
In [68]: CC.A
Out[68]: 'Metaclass A processed'
</code></pre>