在同一个文件中定义多个类是否被认为是Pythonic?


31

在第一次使用python时,我发现我最终在同一文件中编写了多个类,这与Java之类的其他语言(每个类使用一个文件)相反。

通常,这些类由1个抽象基类组成,其中1-2个具体实现的用法略有不同。我在下面发布了一个这样的文件:

class Logger(object):

    def __init__(self, path, fileName):
        self.logFile = open(path + '/' + filename, 'w+')
        self.logFile.seek(0, 2)

    def log(self, stringtoLog):
        self.logFile.write(stringToLog)

    def __del__(self):
        self.logFile.close()

class TestLogger(Logger):   

    def __init__(self, serialNumber):
        Logger.__init__('/tests/ModuleName', serialNumber):

    def readStatusLine(self):
        self.logFile.seek(0,0)
        statusLine = self.logFile.readLine()
        self.logFile.seek(0,2)
        return StatusLine

    def modifyStatusLine(self, newStatusLine):
        self.logFile.seek(0,0)
        self.logFile.write(newStatusLine)
        self.logFile.seek(0,2)

class GenericLogger(Logger):

    def __init__(self, fileName):
        Logger.__init__('/tests/GPIO', fileName):

    def logGPIOError(self, errorCode):
        self.logFile.write(str(errorCode))

如上所示,我有一个Logger基类,下面有几个实现方面的区别。

问题: 此标准适用于python还是任何语言?如果使用此实现,可能会出现什么问题?

编辑:我并不是真正在寻找有关此特定文件的指导,而是从更一般的意义上讲。如果该类最终是3-5个中等复杂的方法,该怎么办?那么将它们拆分会有意义吗?说应该分割文件的临界点在哪里?


3
每个文件限制一个类不是C ++。Java是我所知道的唯一应避免的语言。在C ++中,单个.h / .cpp文件具有一个主类和许多帮助器类是极为常见的,这些辅助类可能是也可能不是该主类专用的。

@StevenBurnap我以删除c ++为例,因为您是正确的。
Ampt入渗

1
它也在php中完成,以方便自动加载。另一方面,在php中,您可以显式声明名称空间。
bodo '16

Answers:


24

没关系。在C ++中也可以,以供参考。

将紧密耦合的东西放在一起是明智的做法。避免不适当的耦合也是一种好习惯。达到适当的平衡不是严格的规则,而是要在不同的问题之间取得平衡。

一些经验法则:

  1. 尺寸

    太大的文件可能很丑陋,但事实并非如此。丑陋可能是分割文件的一个很好的理由,但是发展这种审美意识在很大程度上取决于经验,因此它无助于您先验地做什么。

  2. 关注点分离

    如果您的具体实现有非常不同的内部关注点,则单个文件会累积所有这些关注点。例如,具有不重叠依赖性的实现使您的单个文件依赖于所有那些依赖性的并集。

    因此,有时候考虑子类与其依赖关系的耦合胜于其与接口的耦合可能是合理的(或者相反,实现接口的关注要弱于该实现内部的关注)。

    作为一个具体示例,采用通用数据库接口。分别使用内存数据库,SQL RDBMS和Web查询的具体实现除了界面之外可能没有其他共同点,并且迫使每个想要轻量级内存版本也导入SQL库的人都是讨厌的。

  3. 封装形式

    尽管您可以在同一个模块中编写封装良好的类,但是它可能会鼓励不必要的耦合,因为您可以访问否则不会导出到模块外部的实现细节。

    我认为这只是差劲的风格,但是如果您确实不能改变习惯,则可以通过拆分模块来加强纪律。


2
如果它引用外部引用来证明在一个文件中组合类的正常性,或者通过提供更多解释来说明为什么这样做,您的回答会更强。

1
我已经对问题进行了编辑,以指出这只是我的意思的一个示例,并不完全代表问题的性质。为什么将它们保存在同一文件中比仅在需要时将它们导入更好?
Ampt入渗

拥有很多小文件就像拥有几个大文件一样困难。Python是一种相当简洁的语言。您的示例显示了这一点。这三个类直接相关,并且可能适合单个编辑器窗口而无需滚动。

1
@ GlenH7-我不确定这些参考文献,因为它们只是直接从我提出主张而转向我声称我的选择偏见是有效的。我尝试着重于解释。
2013年

7

我通常的参考文档知道什么是pythonic。

简单胜于复杂。

扁平比嵌套更好。

Python的禅宗

几乎没有例外,类名使用CapWords约定。

程序包和模块名称模块应使用简短的全小写名称。[...]模块名称映射到文件名称

PEP 8

我的解释是这很好,因为它可以使事情变得简单而平坦。另外,由于类名和文件名大小写不同,因此无论如何它们都不相同,因此在文件中打包多个相关类时不会出现任何问题。


7
您能否将其简化为与问题相关的部分?我已经多次阅读了这两本书,但是我很难挑选出与我当前问题特别相关的部分
Ampt入渗

1
确实,我已经编辑了答案。
SylvainD

1

您现在拥有的一切都很好。去浏览标准库-在一个文件中有很多带有多个相关类的模块。在某些时候,事情变得越来越大,您最终将希望开始使用具有多个文件的模块,但是关于时间的确定没有真正的规则。当一个文件开始感觉“太大”时,事情就变得分裂了。


0

绝对可以,我鼓励您在一个文件中有多个类,只要它们能被实现即可。通常,您的班级应该简短而简洁,您应该将行为分为两个或更多班级,而不是构建庞大的整体式班级。当编写几个小类时,将那些相关的类保留在同一文件中确实是必要且有帮助的。


-1

简而言之-是的。

此外,在单个文件中包含多个类有时非常方便。有些软件包(sixbottle)明确船在一个文件中,以便轻松地集成到任何第三方模块而不PIP安装(有时需要)。但是,请确保正确组织代码。大量使用代码注释和分隔块,以使其更具可读性。


3
与几年前发布的先前答案相比,这似乎并没有增加任何实质性内容
gnat 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.