Python 从类(非类成员)范围访问类对象内置值

Python 从类(非类成员)范围访问类对象内置值,python,class,Python,Class,如何从顶级类范围内访问类值?我的意思是,你是怎么做的 class FooClass(object): zeroith_base = __bases__[0] . . . 在本例中,我特别尝试的是派生所有基类的元类,以动态生成一个元类,该元类对所有基类的元类进行子类化,以克服metclass冲突问题。我发现,虽然所有的概念对我来说都是有意义的,但食谱的实际代码超出了我的理解能力。我不想使用我不理解的代码,因此,我尝试实现我自己的、更基本的系统,但在创建过程中,我一

如何从顶级类范围内访问类值?我的意思是,你是怎么做的

class FooClass(object):
    zeroith_base = __bases__[0]
    .
    .
    .

在本例中,我特别尝试的是派生所有基类的元类,以动态生成一个元类,该元类对所有基类的元类进行子类化,以克服metclass冲突问题。我发现,虽然所有的概念对我来说都是有意义的,但食谱的实际代码超出了我的理解能力。我不想使用我不理解的代码,因此,我尝试实现我自己的、更基本的系统,但在创建过程中,我一直在尝试检查类对象。

你会发现
\uu base\uuuu
不是类名称空间的一部分。类名称空间作为第三个参数传递给元类;基数作为第二个参数传递。在创建类之前,它们是完全独立的


因此,您需要做的是编写一个元类来合成您想要的元类,然后使用它来创建类。我不知道这是否真的能起作用,但我看不出它不能起作用的任何原因。

您不能在创建类之前检查它,直到语句集或类主体完成执行,它才被创建。您第一次访问此信息是在创建相关类的类的
元类中。\uuuuu new\uuuuuu
方法中,或者在创建相关类的操作中,技术上不需要是元类或类(如下面的示例所示)

这是一个非常粗略的原型,可能并不适用于所有情况,但适用于简单的情况,并且可能比配方更容易遵循

def meta_class_synthesize(name, bases, attrmap):
    seen = set()
    seen_add = seen.add
    metas = [type(base) for base in bases]
    metas = tuple([
        meta for meta in metas
        if meta is not type and meta not in seen and not seen_add(meta)])
    if not metas:
        return type(name, bases, attrmap)
    elif len(metas) == 1:
        return metas[0](name, bases, attrmap)
    newmeta_name = "__".join(meta.__name__ for meta in metas)
    newmeta = type(newmeta_name, metas, {})
    return newmeta(name, bases, attrmap)

class M_A(type):
    pass

class M_B(type):
    pass

class A:
    __metaclass__ = M_A

class B:
    __metaclass__ = M_B

class C(A, B):
    __metaclass__ = meta_class_synthesize


print type(C)  # prints "<class '__main__.M_A__M_B'>"
def meta_class_synthesis(名称、基数、属性映射):
seen=set()
seen_add=seen.add
metas=[基本中的基本类型(基本)
元=元组([
meta中的meta对meta
如果meta不是类型,meta不在可见和不可见\u添加(meta)])
如果不是metas:
返回类型(名称、基数、属性映射)
elif len(metas)==1:
返回元[0](名称、基数、属性映射)
newmeta_name=“_uu.”加入(meta._name_uu表示meta中的meta)
newmeta=type(newmeta_name,metas,{})
返回newmeta(名称、基数、属性映射)
M_A类(类型):
通过
M_B类(类型):
通过
A类:
__元类
B类:
__元类=M\u B
丙类(甲、乙类):
__元类=元类
打印类型(C)#打印“

是的,我知道我必须创建一个新的元类,它的基础是两个主要类的元类,但我想动态地这样做。如果我是静态的,如果我改变了基类的元类,或者在混合的地方添加了另一个基类和另一个元类,它会把事情分解成一堆又一堆。也许我不清楚,但我相信你可以用元类来做到这一点。让元类执行您在其
\uuuu new\uuuu()
方法中所说的操作。然后使用生成的元类创建类并返回它。它可能需要识别自己,这样就不会进入递归循环。如果这不起作用,我会使用类装饰器来完成这项工作。事实上,这可能更好,因为它在继承层次结构之外。哦,我想我明白了。因此,您是说,从类
C
的元类
MC
,我可以访问
C.\uuuu-bases\uuuu
,这样我就可以从
MC.\uu-new\uuuu()
动态生成一个元类,然后将其用作
C
的元类。请原谅文化上的引用,但是,“我让你喜欢元类,所以我在你的元类中放了一个元类,这样你可以在你的元类中同时使用元类。”是的,这就是事实。一路下来都是Xzibit。好的,是的,这太棒了。我想部分原因是每当我开始思考元类类的本质时,我就会忘记这样一个事实:我正在做的是创建一个包含名称、基和属性的可调用函数。通过减少花哨的步法,这很好地关注了这一事实。