Python类的文件名是否也应该采用驼峰命名法?

122

我知道在Python中类通常使用驼峰式大小写。

如果文件仅包含该类,那么将包含类的文件也命名为驼峰式大小写是正常惯例吗?

例如,className类是否应存储在className.py而不是class_name.py中?


1
https://softwareengineering.stackexchange.com/a/399583/304109 - Benyamin Jafari
骆驼是动物,不是专有名词,因此以小写字母开头,如camelCase。Pascal是一个姓氏,是专有名词,因此以大写字母开头,如PascalCase。 - Scott P.
6个回答

113
以下答案主要参考自这个回答
如果你遵循PEP 8,你应该使用全小写名称,可选下划线。
引用PEP 8关于包和模块的命名惯例
模块名称应当短小,并且全小写。如果下划线可以提高可读性,则可在模块名称中使用。
对于类的命名:
类名通常采用CapWords约定。
关于模块、类和包之间的区别,请参见这个回答
Python模块只是一个Python源代码文件,可以公开类、函数和全局变量。

1
名称应该使用单数形式还是复数形式呢? - gdvalderrama
1
@guival 我认为应该使用单数形式,但可能会有一些例外。我不知道关于复数形式的官方标准,但你可以找到其他关于命名风格最佳实践的讨论,比如这个:https://softwareengineering.stackexchange.com/questions/75919/should-package-names-be-singular-or-plural - Caitlin Quintero Weaver

27

官方约定使用全小写文件名(正如其他人已经说明的那样)。然而,原因还未被提到……

由于Python可以跨平台使用(通常以这种方式使用),但文件系统在大小写使用上存在差异,因此最好消除不同大小写情况。例如,在Linux中,可以在同一目录中有MyClass.py和myclass.py。但在Windows上不能。

另外,如果您在git repo中有MyClass.py和myclass.py文件,或者只是更改相同文件的大小写,当您在Linux和Windows之间进行推送/拉取操作时,git可能会出现问题。

虽然与主题关系不大,但在同一方向上,SQL也存在这些问题,其中不同的标准和配置可能允许表名使用大写字母。

个人而言,我发现即使在文件名中也使用TitleCasing / camelCasing更加愉快,但是如果要跨平台工作,最安全的方式是不使用不同大小写情况。


将文件名全部转换为小写,如何避免在Linux中意外地拥有CapWords风格的文件名?如果问题在于操作系统允许具有不同大小写但相同字母的文件名,则解决方案是始终与您选择的任何命名约定保持一致(全部小写或CapWords-case),而不是完全避免大写。 - R. Navega
1
全小写的文件名可以避免在Linux中意外使用CapWords格式的文件名吗?不会。如果您不小心,无论哪种方式都可能会出现这种问题。Python和其他跨平台语言库的官方标准是使用全小写字母。我在这里提供了一个实际解释,为什么要这样做,这超出了个人喜好的范畴。使用全小写是缓解此问题的一种方法。我经常违反这个“规则”,因为我并不喜欢它。在极少数情况下,它会对我造成影响。 - BuvinJ

12
我的问题是,如果仅包含类的文件是否也应使用camelCase,并且是否也是常规约定。
简短回答:不是。
长回答:应全部小写,并根据需要使用下划线。
来自PEP8“软件包和模块名称”
模块名称应该是短小的、全小写的。如果下划线可以提高可读性,则在模块名称中可以使用下划线。Python软件包的名称也应该是短小的、全小写的,虽然不建议使用下划线。
如果你不清楚模块是什么:
模块是包含Python定义和语句的文件。文件名是模块名称加上后缀.py。

11

类名和包含该类的文件的命名约定不同。这种误解可能来自于像Java这样的语言,其中通常每个类对应一个文件。

在Python中,您可以在一个模块(一个简单的.py文件)中拥有多个类。该模块/文件中的类应按照类命名约定进行命名:类名通常应使用CapWords约定。

包含这些类的文件应遵循模块命名约定:模块应具有短小的全小写名称。如果有助于可读性,则可以在模块名称中使用下划线。

=> CamelCase类名应在camelcase.py文件中(如果必要,可以使用camel_case.py)


我理解你的推理直到最后一句话。 “CamelCase应该在文件camelcase.py中”,你能否澄清你的意思? - MEMark
@MEMark的意思是,对于类CamelCase,请使用文件名camelcase.py - UpTheCreek

6
首先,如上所述,类名应为 CapWords,例如:
class SampleClass:
   ...

注意:使用相同的文件名(模块)和类名容易导致混淆。

例子 1:假设你有以下模块结构:

src/
   __init__.py
   SampleClass.py
main.py

您的SampleClass.py文件如下:
class SampleClass:
   ...

你的 main.py 文件如下:

from src import SampleClass

instance = SampleClass()

这段代码能够正常工作吗?不行,因为你应该使用 from src.SampleClass import SampleClass 或者 instance = SampleClass.SampleClass() 中的一种。代码看起来有点尴尬,不是吗?

你也可以通过在 __init__.py 文件中加入以下内容来解决这个问题:

from .SampleClass import SampleClass

这引出了第二个例子。

例子2:假设你正在开发一个模块:

src/
   __init__.py
   BaseClass.py
   ConcreteClass.py
main.py

BaseClass.py内容:

class BaseClass:
    ...

ConcreteClass.py 的内容:

from src import BaseClass

class ConcreteClass(BaseClass):
    ...

并且你的__init__.py内容:

from .ConcreteClass import ConcreteClass
from .BaseClass import BaseClass

并且 main.py 的内容是:

from src import ConcreteClass

instance = ConcreteClass()

代码出现错误,报错信息如下:
    class ConcreteClass(BaseClass):
TypeError: module() takes at most 2 arguments (3 given)

我花了一些时间才理解错误,以及为什么我不能从这个类继承,因为在之前的例子中,当我将__init__.py文件添加到exports时,一切都正常了。如果您使用蛇形命名法的文件名,这并不能解决问题,但错误会更容易理解:

ImportError: cannot import name 'BaseClass' from partially initialized module 'src'

为了修复代码,您需要在ConcreteClass.py中修复导入的内容,如下所示:from .BaseClass import BaseClass
最后一个注意事项是,如果在原始代码中您会调换__init__.py中的导入顺序,使其看起来像这样:
from .BaseClass import BaseClass
from .ConcreteClass import ConcreteClass

初始代码可以工作,但您确实不希望任何人编写依赖于导入顺序的代码。如果有人更改了顺序或使用 isort 工具来组织导入,那么修复这些错误可就需要好运气了。


1
谢谢您详细的解释,非常好! - Sakthivel

-1

根据你所使用的集成开发环境(IDE),命名约定可能会有所不同。我正在使用Visual Studio Code,遇到了错误提示:Module name "[file name]" doesn't conform to snake_case naming 。我猜“snake_case”意味着所有字母小写,并将所有空格替换为下划线。PEP 8建议如果想要的话可以偶尔使用下划线,但Vsc则要求所有字母小写并且全部使用下划线。所以我认为这可能取决于IDE。


它不取决于集成开发环境(IDE),而是取决于您的项目实施的标准。可以告诉IDE实施不同的标准。 - Destroy666

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接