【发布时间】:2020-04-26 01:42:07
【问题描述】:
所以我有一个类结构,其中包含多个级别的内部类嵌套,用于命名空间。这与将所有东西都放平没有什么不同,但这种方式更加简洁直观。基本上,我们使用内部类来更好地组织代码。
我遇到了一些问题:
我只是发布一些示例代码而不是试图解释它们:
1)
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.Subclass1 时Namespace1.Class1 还不存在,所以它不起作用。我假设可能没有办法解决这个问题,但我提到这一点以防万一我不知道有什么方法可以实现。
所以我接下来尝试的是:
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.
这很有效,但我真的不喜欢它有几个原因:
- 我们现在得到子类之间的命名空间冲突,所以我们不能再调用它们(
Subclass1,Subclass2,...),现在必须调用它们(Class1Subclass1,Class1Subclass2, ...) - 我们现在已经失去了使层次结构在视觉上明确的额外缩进级别,一旦嵌套 4 层深度并且类名开始变得像 6 个单词一样长,这会很糟糕
所以我想到了这样做:
2)
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 行长)将是一场噩梦。
【问题讨论】:
-
只是一个想法:每个类需要是自己的全局名称吗?您可以在容器中存储对其他匿名类的引用。
-
模块本身已经是一个命名空间。并且嵌套类定义(通常)被认为是非常不符合 Python 的(Python 之禅:“扁平比嵌套更好”)。注意:我不建议每个类使用一个模块(这确实是一个 PITA,并且至少与嵌套类一样 unpythonic),只是不要以这种方式嵌套你的子类。
-
另外,你有这么多子类“只有一个方法覆盖不同”的事实对我来说有点设计味道。当然,如果不了解更多关于真实上下文和用例的信息,就不可能说出来,但也许像策略模式这样的东西可能更合适?
标签: python python-3.x class oop namespaces