【问题标题】:Defining a class property within __init__ as opposed to within another class method -- python在 __init__ 中定义一个类属性,而不是在另一个类方法中——python
【发布时间】:2015-11-16 16:15:09
【问题描述】:

编辑

注意,我注意到Instance attribute attribute_name defined outside __init__ 可能是重复的,我基本同意(我没有遇到这个,因为我不知道要搜索 pylint)。但是,我想保持这个问题是开放的,因为我希望能够使用相同的方法重新初始化我的类。上一个问题的普遍共识是从loadData脚本中返回每个参数,然后解析成self对象。这很好,但是,我仍然需要在另一个方法中再次这样做才能重新初始化我的类实例,这似乎仍然是额外的工作,只是为了提高一点可读性。也许这个问题就是我的例子。在现实生活中,loadData 例程会读取大约 30 个参数,这就是为什么我不愿意在两个不同的位置解析它们的原因。

如果这里的普遍共识是返回参数是可行的方法,那么我们可以继续并关闭这个问题作为重复;但是,与此同时,我想等一下,看看其他人是否有任何想法/一个很好的解释。


原创

这是一个“最佳实践”问题。我最近一直在学习 python(部分是为了学习新的东西,部分是为了远离 MATLAB)。在 python 中工作时,我创建了一个结构如下的类:

class exampleClass:
    """
    This is an example class to demonstrate my question to stack exchange
    """

    def __init__( self, fileName ):
        exampleClass.loadData( self, fileName )

    def loadData( self, fileName ):
        """
        This function reads the data specified in the fileName into the 
        current instance of exampleClass.
        :param fileName: The file that the data is to be loaded from
        """

        with open(fileName,'r') as sumFile:
            self.name = sumFile.readLine().strip(' \n\r\t')

现在这对我来说很有意义。我有一个初始化类,它通过调用填充函数来填充类的当前实例。我还有人口功能,如果出于某种原因需要,我可以重新初始化此类的给定实例(例如,如果该类占用大量内存,而不是创建我只想创建的单独的类实例有一个我覆盖的实例。

但是,当我将此代码放入我的 IDE (pycharm) 中时,它会抛出一个警告,指出实例属性是在 __init__ 之外定义的。现在显然这不会影响代码的运行,一切正常,但我想知道在这种情况下是否有任何理由要注意警告。我可以做一些事情,在调用loadData method 之前在init 方法中将所有属性初始化为某个默认值,但这对我来说似乎是不必要的工作,并且会减慢执行速度(尽管只是很小的数量)。我还可以拥有 loadData 方法的两个副本,一个在 __init__ 方法中,另一个作为实际方法,但这似乎又是不必要的额外工作。

总的来说,我的问题是在这种情况下最佳做法是什么。是否有任何理由我应该以我在上一段中提到的一种方式重构代码,或者这只是一个带有过于广泛的代码检查警告的 IDE 实例。我显然可以看到一些需要考虑此警告的情况,但根据我目前的经验,在这种情况下它看起来不是问题。

【问题讨论】:

标签: python pycharm code-inspection


【解决方案1】:

我认为最好预先定义所有属性,即使您稍后要重新定义它们。当我阅读您的代码时,我希望能够看到您的数据结构。如果某个方法中隐藏的某些属性仅在某些情况下才被定义,那么代码就更难理解了。

如果不方便或不可能给属性赋予最终值,我建议至少将其初始化为None。这向读者表明该对象包含该属性,即使它稍后被重新定义。

class exampleClass:
    """
    This is an example class to demonstrate my question to stack exchange
    """

    def __init__( self, fileName ):
        # Note: this will be modified when a file is loaded
        self.name = None

        exampleClass.loadData( self, fileName )

另一个选择是 loadData 返回值而不是设置它,因此您的 init 可能如下所示:

def __init__(self, fileName):
    self.name = self.loadData(fileName)

我倾向于认为第二种方法更好,但任何一种方法都可以。关键是,让你的类和对象尽可能容易理解。

【讨论】:

  • 谢谢@Bryan,我同意这里的观点。正如我刚刚在编辑中提到的,我犹豫第二个的唯一原因是因为有很多参数并且必须解析它们两次似乎过度。也许我只是将变量初始化为它们的默认类型,然后从那里开始。我会考虑一下,并在接受您的回答之前等待看看是否有其他人回复。
  • 仅适用于偶然发现此内容的任何人。我决定按照 Bryan 的建议先初始化所有属性。我走这条路是因为我不想解析来自loadData 的输出两次。如果管理员认为这是重复的并想关闭它,我对此没有任何问题,但现在我认为除了其他问题之外它很有用。
猜你喜欢
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 2020-09-17
  • 1970-01-01
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
相关资源
最近更新 更多