是否有在 __init__ 方法中定义变量的最佳实践

Is there a best practice for defining variables in _init_ method

__init__ 方法中定义对象变量的方式是否有任何充分的理由,您应该使用 self.var 还是仅使用 var.

构建新变量

重要吗?有微观的速度优势吗?

就我个人而言,我更喜欢后者,因为后者更清晰,文本更少。但我经常看到两者。

class Person():
    def __init__(self, firstname, lastname):
        self.first = firstname
        self.last = lastname
        self.fullname = self.first + ' ' + self.last

或:

class Person():
    def __init__(self, firstname, lastname):
        self.first = firstname
        self.last = lastname
        self.fullname = firstname + ' ' + lastname

本地名称稍微快一些,所以first,而不是self.first,因为后者需要查找本地名称self,然后查找属性first在那个物体上。与所有其他查找相比,局部变量的使用得到了高度优化。

然而,差异很小,关注这一点是过早的优化。只有在关键代码中必须多次使用相同的变量负载时才需要担心这一点。

如果忽略性能差异,那么归结为需求和清晰度;实例属性的行为可能与局部变量非常不同,这可能是一个优势:

  • 如果您需要支持想要改变 self.firstself.last 在分配给或访问时的行为方式(使用 property)的子类,则你会想要使用这些属性。

  • 另一方面,使用局部参数名称可以清楚地表明 fullname 独立于 self.firstself.last 的行为方式(如果不是简单的属性)。那可能是故意的。

我们不能在这里给出任何更具体的指导方针,因为属性可以很容易地支持本地人的不同用例。

如果您确实需要担心性能,请使用 timeit module 到 运行 微基准:

>>> from timeit import timeit
>>> class PersonAttributes():
...     def __init__(self, firstname, lastname):
...         self.first = firstname
...         self.last = lastname
...         self.fullname = self.first + ' ' + self.last
...
>>> class PersonLocals():
...     def __init__(self, firstname, lastname):
...         self.first = firstname
...         self.last = lastname
...         self.fullname = firstname + ' ' + lastname
...
>>> timeit('P("Eric", "Idle")', 'from __main__ import PersonAttributes as P')
0.5858714409987442
>>> timeit('P("Eric", "Idle")', 'from __main__ import PersonLocals as P')
0.5170505980058806

上面创建了一个实例 100 万次,此时您将通过使用本地名称节省 40 毫秒。