在__init__中定义类属性而不是在另一个类方法中定义 - python

时间:2015-11-16 16:15:09

标签: python pycharm code-inspection

修改

请注意,我注意到Instance attribute attribute_name defined outside __init__可能是重复的,我大多赞同(我没有遇到这个,因为我不知道要搜索pylint)。但是,我想保持这个问题是开放的,因为我希望能够使用相同的方法重新初始化我的类。上一个问题的一般共识是从loadData脚本返回每个参数,然后将其解析为自身对象。这很好,但是,我仍然需要在另一个方法中再次执行此操作,以便能够重新初始化我的类实例,这仍然看起来像额外的工作只是为了更多的可读性。也许这个问题就是我的榜样。在现实生活中,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')

现在这对我有意义。我有一个init类,通过调用一个填充函数来填充该类的当前实例。如果由于某种原因我需要(例如,如果类占用了大量内存而不是创建类的单独实例,我还想拥有),那么我也可以使用该函数来重新初始化该类的给定实例。有一个我覆盖的实例。

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

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

1 个答案:

答案 0 :(得分:2)

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

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

SELECT a.name1,
       a.name2,
       b.*
FROM 
( SELECT name1, name2 FROM dummy1
   WHERE id IN ('1', '2', '3', '4', '5', '6', '7', '8') ) a
JOIN dummy2 b
       ON b.a_id=a.id where ...;

另一个选择是None返回值而不是设置它,所以你的init可能看起来像:

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 )

我倾向于认为第二种方法更好,但两种方法都没问题。关键是,让您的类和对象尽可能易于理解。