Python中的实例variables与类variables

我有Python类,其中我只需要在运行时的一个实例,所以每个类只有一个属性,而不是每个实例只是一个属性。 如果将有多个实例(这不会发生),则所有实例都应具有相同的configuration。 我不知道以下哪个选项会更好或者更“惯用”Python。

类variables:

class MyController(Controller): path = "something/" children = [AController, BController] def action(self, request): pass 

实例variables:

 class MyController(Controller): def __init__(self): self.path = "something/" self.children = [AController, BController] def action(self, request): pass 

如果你只有一个实例,最好每个实例都创build一个variables,只是因为它们会被更快地访问(一点点的“查找”,因为每个类的“inheritance”),没有什么缺点可以衡量这个小小的优势。

进一步回应迈克和亚历克斯的build议,并添加我自己的颜色…

使用实例属性是典型的,更习惯的Python。 class属性并没有经常使用 – 至less在我连续13年的Python中没有生产代码。 静态方法和类方法也是如此……除非有特定用例或exception程序员想炫耀他们知道Python编程的一些不起眼的angular落,否则不是很常见。

alex在他的回答中提到,由于less一级的查询,访问将会(稍微快一点)…让我进一步澄清那些不知道如何工作的人,这与variables访问非常相似 – – search按以下顺序进行:

  1. 当地人
  2. nonlocals
  3. 全局
  4. 内置插件

对于属性访问,顺序是:

  1. 由MRO确定的基类(方法parsing顺序)

在上面的例子中,假设你正在查找path属性。 当遇到像“ self.path ”这样的引用时,Python会首先查看实例属性, 当它失败时,它检查从中实例化对象的类。 最后,它会search基类。 正如亚历克斯所说,如果你的属性是在实例中发现的,它不会延迟到课堂,因此你节省了一点时间。

然而,如果你坚持类属性,你将不得不放弃这一小部分的性能, 或者 ,你的另一种select是通过类而不是实例引用对象,例如MyController.path而不是self.path 。 这是一个直接的查找,可以避开延迟查找,但是如下面的alex提到的,这是一个全局variables,所以你失去了那一点,你认为你会保存(除非你创build一个局部引用到[global]类的名字)。

如果有疑问,您可能需要一个实例属性。

类属性最好保留在有意义的特殊情况下。 唯一很常见的用例是方法。 对于实例需要知道的只读常量,使用类属性并不less见 (尽pipe这样做的唯一好处是如果你也想从类外部访问),但是你一定要谨慎地存储它们中的任何状态,这很less是你想要的。 即使你只有一个实例,你也应该像其他任何类一样写类,这通常意味着使用实例属性。