如何在Python中构建继承类的层次视图?

2024-09-27 23:23:05 发布

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

这是一个我多次试图回避的问题,但在最近的一个项目中,我最终还是无法回避这个问题。我尝试了各种解决方案,并决定使用其中之一,并愿意与您分享。互联网上的许多解决方案根本不起作用,我认为它可以帮助那些不太流利的人学习类和元类。你知道吗

我有类的层次结构,每个类都有一些在实例化对象时需要读取的类变量。但是,如果这些变量的格式为__variable,则它们的名称将被覆盖或损坏。我可以很好地处理被损坏的变量,但是我不知道,绝对肯定地说,我应该在我的对象的名称空间中查找哪个属性。下面是我的定义,包括类变量。你知道吗

class BasicObject(object):
    __attrs = 'size, quality'
    ...

class BasicDBObject(BasicObject):
    __attrs = 'db, cursor'
    ...

class DbObject(BasicDBObject):
    __attrs = 'base'
    ...

class Splits(DbObject):
    __attrs = 'table'
    ...

我想在实例化Splits类时收集每个类的__attrs中存储的所有值。方法__init__()只在类BasicObject中定义,其他地方没有定义。不过,我需要扫描self.__dict__以查找损坏的__attrs属性。由于其他属性在这些对象中具有模式attrs,因此我无法筛选出字典中所有具有模式__attrs的内容!因此,我需要收集对象的类层次结构,并搜索所有这些类的损坏属性。你知道吗

因此,我将使用metaclass来捕获每个类,这些类调用在加载模块时遇到class定义时正在执行的__new__()方法。通过在基类中定义我自己的__new__()方法,我将能够在实例化每个类时捕获类(实例化class,而不是对象实例化)。你知道吗

代码如下:

import collections

class BasicObject(object) :
    class __metaclass__(type) :
        __parents__ = collections.defaultdict(list)

        def __new__(cls, name, bases, dct) : 
            klass = type.__new__(cls, name, bases, dct)
            mro = klass.mro()
            for base in mro[1:-1] :
                cls.__parents__[name] = mro[1]

            return klass


    def __init__(self, *args, **kargs) :
        """
        Super class initializer.
        """

        this_name = self.__class__.__name__
        parents = self.__metaclass__.__parents__
        hierarchy = [self.__class__]
        while this_name in parents :
            try :
                father = parents[this_name]
                this_name = father.__name__
                hierarchy.append(father)
            except :
                break

        print(hierarchy)
        ...

我可以使用类定义获得访问属性,但是所有这些类都是在三个不同的模块中定义的,主模块(init.py)对其他模块一无所知。你知道吗

这段代码在Python2.7中运行良好,也应该在Python3中运行。。但是,python3。有一些新特性,可能有助于为这种自省编写更简单的代码,但我还没有时间在python3.0中研究它。你知道吗

我希望这个简短的解释和例子能为您节省一些宝贵的时间:-)


Tags: 模块对象实例方法nameselfnew属性

热门问题