18

Python中命名接口和抽象类的约定是什么?PEP 8没有讨论这个。例如,在 Java 中,接口通常以I前缀命名。在 PHP(在命名空间之前)中,抽象类通常使用_Abstract后缀命名。

(我意识到Pythonists并不热衷于接口,也许这就是我在这个话题上找不到太多共识的原因。但是接口和抽象类的使用不是我的问题。)

4

4 回答 4

12

除了PEP8之外,我不知道在这方面有任何社区范围的标准,它没有具体解决这个问题。

我建议做任何你的团队最舒服的事情,但最重要的是要保持一致

于 2012-05-23T16:13:07.633 回答
10

我会查看数字塔(来自numbers)、集合 ABC(来自collections.abc)或其他核心 ABC(例如importlib.abc),以获得最“Pythonic”的方式来执行此操作。

对此的共识是按原样命名它们,并让人类理解将它们识别为抽象的。

于 2015-11-04T20:11:52.747 回答
9

我认为用前缀命名接口I是完全可以接受的。

例如:

  • IFoo
  • IPublishable

几年前,我使用了 Zope Interfaces。我注意到大多数代码库都使用这种约定。我们的团队也这样做了。

我们更喜欢IFooFooInterfaceIFooInterface

于 2012-05-23T17:17:36.417 回答
0

TL;博士

如果您不关心类型提示,请随意命名它们。否则,ABCs是您为其他开发人员提供的 API。他们的名字应该是干净的,没有任何杂乱。具体的实现应该会告诉你为什么它很特别。

打电话给你的班级UserServerUserLocalUser


为什么我们首先需要这样的约定?

第一个应该问自己的是,我们为什么要关心类的命名?

静态类型语言(python 不是)中,您的接口名称代表一个 API,其他开发人员通过该 API 与您的代码进行交互。所以函数的调用者应该很快就能理解参数和返回类型的含义。Java 中的一个示例(其中前缀 Interfaces 前段时间已经过时..)将是:

public void signupUsers(Collection<User> users) {
    // TODO: do something with users
}

在这里,我们希望名称尽可能纯净。我们接受任何Collection和任何User。它可能是ArrayList,或HashSet,我们不在乎。LocalUserServerUser

为什么 Python 中没有这样的标准?

这与 python 无关,因为它是一种动态类型语言。在下面的代码中,你不需要关心类是如何被调用的:

def signup_users(users):
    pass  # TODO: do something with users

你只会在创建一个类并检查它的类型时才有意义,这不足以证明一个完整的命名约定是合理的

为什么现在有人会关心 Python 中的类命名?

但是由于引入了类型模块,事情正在发生变化。您现在可以显式声明类型。如果我们想接受这个新特性,我们应该考虑类的命名。

那么我们的类应该取什么名字呢?

按照与为什么其他语言放弃接口前缀的相同逻辑,我相信ABCs(如果它们与接口起类似的作用)应该有一个干净的名称。like 的名称比 .User好读得多IUser。如果您有用户的具体实现,那么该实现的名称应该告诉您它有什么特别之处。是使用来自服务器的数据更新数据的用户吗?调用它ServerUser。您是否在本地存储用户数据?调用它LocalUser

def signup_users(users: Iterable[User]) -> None:
    pass  # TODO: do something with users

关心实现细节的“丑陋”代码如下所示:

lovelace = LocalUser("Aida", "Lovelace", 1815)
babbage = ServerUser("htts://some_service.com/users/charles_babbage")
signup_users([aida, babbage])

这将处理复杂名称的负担放在必须处理实现的调用者身上——因为它应该

于 2022-02-13T10:04:40.933 回答