【问题标题】:Python instance variablesPython 实例变量
【发布时间】:2020-04-10 17:52:01
【问题描述】:

在声明你的类实例变量时,你可以调用类的方法之一来初始化你的构造函数中的一个实例变量吗?例如,假设我有一个 Button 类,以及该类中的一个方法 methodA(),它将名为“active”的变量设置为 False。我可以通过调用该方法来初始化“活动”吗?

class Button:
    def __init__(self):
        *snip*
        self.methodA()

    def methodA(self):
        self.active = False

这种技术对于初始化我的实例变量“活动”是否正确?

【问题讨论】:

  • 是的,你可以,但是为什么你会这样做而不是在init方法中设置self.active = False
  • 这是一个很好的问题 - 我正在研究 Zelle Python Programming 第 3 版。教科书,这就是他设置的方式。他正在报道一个炮弹发射项目,并通过调用 deactivate() 方法为名为“活动”的按钮状态初始化布尔实例变量,因此任何按钮都将具有“活动”= False 的初始值。 deactivate() 方法确实做了一些其他的事情,即它为一些其他实例变量添加了更多的颜色和线宽格式,这些实例变量在初始化时会被 deactivate() 方法进一步强调。

标签: python variables constructor instance


【解决方案1】:

是的,可以这样做。事实上,在 Python 中,任何非静态方法都可以为类的对象初始化新的数据成员。但是,建议始终初始化 __init__() 中的成员,因为在对象创建和初始化时初始化要使用的成员被认为是一种很好的做法。

【讨论】:

    【解决方案2】:

    在您的评论中添加上下文后,您的问题就更有意义了。是的,您可以在另一种方法中设置对象的任何属性。实际上,由于 Python 的动态类型,您甚至可以在对象初始化之后设置它们:

    class Example:
        pass
    
    e = Example()
    e.foo = 'bar'
    e.foo  # returns 'bar'
    

    然而,一般来说,您希望在其__init__ 方法中初始化对象的所有属性,因为它更易于维护,并且当您不记得是否定义了特定属性或在哪里定义时,您总是知道在哪里查看它来自。

    在您的示例中,使用它曾经拥有的所有属性初始化您的类,然后调用方法来修改它们更有意义。例如:

    class Button:
        def __init__(self):
            *snip*
            self.active = False
            self.color = 'red'
            self.linewidth = 2
    
        def activate(self):
            self.active = True
            self.color = 'green'
            self.linewidth = 5
    
        def deactivate(self):
            self.active = False
            self.color = 'red'
            self.linewidth = 2
    

    现在您可能注意到我们有代码重复 - __init__ 方法基本上复制了 deactivate 方法中的行!尽管如此,在 __init__ 方法中包含所有属性对于可读性来说还是很棒的。我们该怎么办?

    考虑这种折衷方案:使用None 值初始化所有属性,然后调用deactivate 方法:

     class Button:
        def __init__(self):
            *snip*
            self.active = None
            self.color = None
            self.linewidth = None
            self.deactivate()
    
        def activate(self):
            self.active = True
            self.color = 'green'
            self.linewidth = 5
    
        def deactivate(self):
            self.active = False
            self.color = 'red'
            self.linewidth = 2
    

    这结合了两全其美:我们的代码是可读的(__init__ 方法基本上读作“使用这些属性初始化一个按钮,然后停用它”),但也没有代码重复。

    This question 补充了一些关于为什么最好在 __init__ 方法中创建所有属性的见解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 2011-02-12
      相关资源
      最近更新 更多