内部类作用域的问题

2024-05-03 20:29:15 发布

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

因此,我得到了一个类结构,其中有几个级别的内部类嵌套,用于名称空间。这和把所有东西都放平没什么区别,但这样做更干净、更直观。基本上,我们使用内部类来更好地组织代码

然而,我遇到了一些问题:

我将只发布一些示例代码,而不是试图解释它们:

(一)

class Namespace1:
    class Class1:
        pass  # base methods go here

        class Subclass1(Namespace1.Class1):
            pass  # extended methods go here

        class Subclass2(Namespace1.Class1):
            pass  # extended methods go here

        class Subclass3(Namespace1.Class1):
            pass  # extended methods go here

    class Class2:
        pass  # base methods go here

        class Subclass1(Namespace1.Class2):
            pass  # extended methods go here

        # etc.

这里子类化的问题是Namespace1.Class1在您尝试声明Namespace1.Class1.Subclass1时还不存在,因此它不起作用。我假设可能没有办法解决这个问题,但我提到这一点只是为了以防万一,有什么方法可以达到我不知道的目的

所以我接下来尝试的是:

class Namespace1:
    class Class1:
        pass  # base methods go here

    class Class1Subclass1(Class1):
        pass  # extended methods go here

    class Class1Subclass2(Class1):
        pass  # extended methods go here

    class Class1Subclass3(Class1):
        pass  # extended methods go here

    class Class2:
        pass  # base methods go here

    class Class2Subclass1(Class2):
        pass  # extended methods go here

        # etc.

这很有效,但我真的不喜欢它,原因有几个:

  • 我们现在得到子类之间的名称空间冲突,因此我们不能再调用它们(Subclass1Subclass2,…),现在必须调用它们(Class1Subclass1Class1Subclass2,…)
  • 现在,我们已经失去了额外的缩进级别,这些缩进级别可以使层次结构在视觉上清晰可见。一旦嵌套了4个级别,并且类名开始变长6个单词,这就太糟糕了

所以我想这样做:

(二)

class Namespace1:
    class Class1:
        pass  # base methods go here

    class Class1_:
        class Subclass1(Class1):
            pass  # extended methods go here

        class Subclass2(Class1):
            pass  # extended methods go here

        class Subclass3(Class1):
            pass  # extended methods go here

    class Class2:
        pass  # base methods go here

    class Class2_:
        class Subclass1(Class2):
            pass  # extended methods go here

        # etc.

这不是100%的理想(最好的方法是上面的示例1),但理论上这应该是可能的。当解释器开始创建Namespace1.Class1_.Subclass1时,Class1应该已经存在了。我遇到的问题是,我不知道如何引用它,因为我不能仅仅将它引用为Namespace1.Class1(因为Namespace1还不存在),我无法将它简单地引用为Class1

有人知道我会怎么做吗

在任何人告诉我只使用模块层次结构来实现这一点之前:我知道这是一个选项,但我更喜欢将其全部放在一个文件中,这样就有了一个单一的概述,因为这些类中的每个类都只有大约3-5行长(只因单个方法重写不同)。对于这个特定的用例,最好在一个地方看到它,我得到的实际代码有3-4级缩进,有些类有12+个子类。浏览100多个文件(每个文件可能有10行长)将是一场噩梦


Tags: 代码extendedgobasehereetcpass级别
1条回答
网友
1楼 · 发布于 2024-05-03 20:29:15

嵌套类存储为外部类的属性,因此,与其在声明中直接指定每个嵌套类的基类,不如在声明中直接指定每个嵌套类的基类,因为您已经描述了不能这样做的原因,通过调用type函数,将外部类添加到每个内部类作为基类,可以使用外部类上的类装饰器将这些属性转换为外部类的子类:

def nested_subclasses(cls):
    for name, obj in vars(cls).items():
        if isinstance(obj, type):
            setattr(cls, name, type(name, (cls,), dict(vars(obj))))
    return cls

以便:

class Namespace1:

    @nested_subclasses
    class Class1:
        def foo(self):
            print('bar')

        class Subclass1:
            pass

Namespace1.Class1.Subclass1().foo()

产出:

bar

相关问题 更多 >