在Python中使用未初始化的变量

时间:2011-08-10 01:53:17

标签: python initialization pylint

背景:我有一个用寄存器建模芯片的类,芯片有一堆寄存器,其中一个是内置温度传感器的高温限制。

我有以下内容:

class foo():
  def __init__(self):
    # does not set self._hiTemp!
    ...
  def setHiTemp(self, t):
    self._hiTemp = t
  def getHiTemp(self):
    return self._hiTemp
  def checkHiTemp(self):
    return self._temp > self._hiTemp

我没有在self._hiTemp中声明__init__的原因是因为用户可能不关心芯片的温度感应功能。用户可以以不同的方式使用芯片,并且赋予该变量无意义的值没有意义。但是,如果用户在没有先设置它的情况下尝试使用self._hiTemp,则使用未声明变量的错误比一些模糊错误(例如比较数字和无)(或者在某些情况下甚至根本没有错误)更容易调试/回溯)。

这一切都很好,直到我开始pylint,当然我得到W0201:在 init 之外定义的属性几乎无处不在。我只是想知道这种编码风格是否令人不悦,如果是这样,那么“Pythonic方式”是什么。

由于

5 个答案:

答案 0 :(得分:11)

我这样做的方法是将其设置为None或其他一些不会在“自然”中出现的哨兵值。然后,对于需要设置它的操作,如果调用者试图不恰当地使用您的对象,请使用assert快速失败。

def __init__(self):
    self._hiTemp = None

def checkHiTemp(self):
    assert self._hiTemp is not None, 'Why you no set _hiTemp before checking it?'
    return self._temp > self._hiTemp

答案 1 :(得分:6)

Python不是Java,所以不要写那样的getter和setter。你可以像这样解决你的问题

class Foo(object):
    def __init__(self, hiTemp=None):
        self._hiTemp = hiTemp

    @property
    def hiTemp(self):
        if self._hiTemp is None:
            raise AttributeError("You have not initialized hiTemp")
        return self._hiTemp

    @hiTemp.setter
    def hiTemp(self, value):
        self._hiTemp = value

    def checkHiTemp(self):
        return self._temp > self._hiTemp

foo=Foo()
foo.hiTemp = 50
print foo.hiTemp # Prints 50

foo=Foo(hiTemp=20)
print foo.hiTemp # Prints 20

foo=Foo()
print foo.hiTemp # Raises exception

答案 2 :(得分:1)

如果您希望通过方法设置对象的特定属性,则始终有理由在初始化程序中可用。您可以使用self._hiTemp=None您已经通过引导_将其声明为私有,因此用户将理解为不依赖于此。

答案 3 :(得分:0)

习惯上使用值None来表示没有实际价值。您可以将其初始化为__init__中的内容。在这种情况下,您也可以使用无意义的值,例如负数,并在checkHiTemp方法中检查它,如果在没有正确初始化值的情况下使用,则引发自定义异常。这是一个更有意义的错误。

答案 4 :(得分:0)

我认为从用户的角度来看,有一个正确的错误消息比未声明的变量错误更好。我愿意:

def __init__(self):
    self._hiTemp = None

def setHiTemp(self, t):
    self._hiTemp = t

def getHitemp(self):
    if self._hiTemp is None:
        raise Exception('You need to setHiTemp() before using it.')
    else:
        return self._hiTemp

def checkHiTemp(self):
    if self._hiTemp is None:
        raise Exception('You need to setHiTemp() before using it.')
    else:
        return self._temp > self._hiTemp