在类绑定到模块namesp之后完成它

2024-05-29 10:11:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法来完成类的创建,以便在python pre-3.3中重新创建__qualname__。我的元类QualNameMeta递归地设置__qualname__,并将其传播给成员。由于这种工作方式,当类被添加到模块时,我需要执行一个函数。你知道吗

因为函数没有主动参与,所以我需要测试结果来标记不可访问的qualnames。你知道吗

class Scope1(object):
    __metaclass__ = QualNameMeta
    def scope_f(self):
        class ScopeF(object):
            __metaclass__ = QualNameMeta
        return ScopeF
    print scope_f.__qualname__ # gives correct Scope1.scope_f
    print scope_f().__qualname__ # gives ScopeF, should be None or Scope1.scope_f.<locals>.ScopeF

此测试可以在创建后轻松执行(不包括展开魔法):

def test_qualname(obj):
    namespace = sys.modules[obj.__module__]
    for name in obj.__qualname__.split('.'):
        try:
            namespace = getattr(namespace, name)
        except AttributeError:  # name does not point to any object
            return False
    return namespace is obj  # make sure we got the right one

但是,我不能直接从元类中得到它。如果我在QualMeta.__new__QualMeta.__init__中调用test_qualname,则对象尚未绑定到模块。因此,我需要一种方法在对象绑定到模块之后执行检查。你知道吗

为什么不是装饰师? 我需要它来持久地处理继承,这样就可以通过只修改基类来修补整个类层次结构。使用元类是迄今为止我找到的唯一解决方案。你知道吗


一个最小的虚拟示例:

class QualMeta(type):
    def __new__(mcs, name, bases, class_dict):
        new_cls = type.__new__(mcs, name, bases, class_dict)
        new_cls.__qualname__ = name  # dummy for top-level only
        if not test_qualname(new_cls):  # new_cls is not bound yet, test will fail
            new_cls.__qualname__ = None
        return new_cls


class Qualnamed(object):
    __metaclass__ = QualMeta

print(Qualnamed.__qualname__)  # gives None

Tags: 模块nametestobjnewreturnobjectnamespace
1条回答
网友
1楼 · 发布于 2024-05-29 10:11:40

您需要在class_dict中设置新属性,并让type.__new__()进行绑定:

class QualMeta(type):
    def __new__(mcs, name, bases, class_dict):
        class_dict['__qualname__'] = name
        new_cls = type.__new__(mcs, name, bases, class_dict)
        return new_cls

class Qualnamed(object):
    __metaclass__ = QualMeta

print(Qualnamed.__qualname__)  # print "Qualnamed"

相关问题 更多 >

    热门问题