嵌套的Python类需要访问封闭类中的变量

发布于 2021-01-29 14:58:35

我已经看到了一些“解决方案”,但是每次的解决方案似乎都是“不要使用嵌套类,在外部定义类,然后再正常使用它们”。我不喜欢这个答案,因为它忽略了我选择嵌套类的主要原因,即拥有一个常量池(与基类相关联),该常量池可用于所有创建的子类实例。

这是示例代码:

class ParentClass:

    constant_pool = []
    children = []

    def __init__(self, stream):
        self.constant_pool = ConstantPool(stream)
        child_count = stream.read_ui16()
        for i in range(0, child_count):
            children.append(ChildClass(stream))

    class ChildClass:

        name = None

        def __init__(self, stream):
            idx = stream.read_ui16()
            self.name = constant_pool[idx]

所有类都传递一个参数,这是一个自定义的位流类。我的目的是要提供一种解决方案,该解决方案不需要我仍在ParentClass中时读取ChildClass的idx值。所有子类流读取都应在子类中进行。

此示例过于简化。常量池不是我需要用于所有子类的唯一变量。idx变量不是从流读取器读取的唯一内容。

在python中甚至可能吗?没有办法访问父母的信息吗?

关注者
0
被浏览
115
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    尽管我发表了“有点光顾”的评论(公平地称呼它!),实际上还是有一些方法可以实现您想要的:继承的另一种途径。一对夫妇:

    1. 编写一个装饰器,该装饰器在声明一个类后立即对其进行内省,找到内部类,并将属性从外部类复制到它们中。

    2. 用元类做同样的事情。

    这是装饰器方法,因为它是最简单的方法:

    def matryoshka(cls):
    
        # get types of classes
        class classtypes:
            pass
        classtypes = (type, type(classtypes))
    
        # get names of all public names in outer class
        directory = [n for n in dir(cls) if not n.startswith("_")]
    
        # get names of all non-callable attributes of outer class
        attributes = [n for n in directory if not callable(getattr(cls, n))]
    
        # get names of all inner classes
        innerclasses = [n for n in directory if isinstance(getattr(cls, n), classtypes)]
    
        # copy attributes from outer to inner classes (don't overwrite)
        for c in innerclasses:
            c = getattr(cls, c)
            for a in attributes:
                if not hasattr(c, a):
                    setattr(c, a, getattr(cls, a))
    
        return cls
    

    这是其用法的一个简单示例:

    @matryoshka
    class outer(object):
    
        answer = 42
    
        class inner(object):
    
            def __call__(self):
                print self.answer
    
    outer.inner()()   # 42
    

    但是,我不禁认为其他答案中提出的一些想法会更好地为您服务。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看