如何在 Python 中构建继承类的分层视图?
Posted
技术标签:
【中文标题】如何在 Python 中构建继承类的分层视图?【英文标题】:How to build a hierarchical view of inherited classes in Python? 【发布时间】:2015-04-30 06:26:40 【问题描述】:这是我多次试图回避的问题,但在最近的一个项目中,我终于无法逃避这个话题。我尝试了各种解决方案并决定使用其中一种,并希望与您分享。互联网上的许多解决方案根本不起作用,我认为它可以帮助那些对类和元类不太流利的人。
我有类的层次结构,每个类都有一些我在实例化对象时需要读取的类变量。但是,这些变量要么被覆盖,要么它们的名称如果具有__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
来捕获每个调用__new__()
方法的类,该方法在加载模块时遇到class
定义时正在执行。通过在基类中定义我自己的 __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
) 对其他模块一无所知。
此代码在 Python 2.7 中运行良好,也应该在 Python 3 中运行。。然而,Python 3. 有一些新特性可能有助于为这种内省编写更简单的代码,但我没有时间在 Python 3.0 中研究它。
我希望这个简短的解释和示例可以节省您的一些(宝贵的)时间:-)
【问题讨论】:
我认为你的 answer 应该放在.. 答案中。 是的,你完全正确!但我不知道如何直接发布“答案”:-) 【参考方案1】:是的,问题就是答案;只是因为我找不到网站上的“”按钮以外的任何东西。我错过了什么吗?
【讨论】:
以上是关于如何在 Python 中构建继承类的分层视图?的主要内容,如果未能解决你的问题,请参考以下文章
如何从基类的ObserveableCollection显示子类的属性? [关闭]
python类的继承!!谁能用通俗的方法,给小弟讲一下,类的继承!!
JavaScript是如何工作的:深入类和继承内部原理 + Babel和TypeScript之间转换