5

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

我有以下内容:

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: Attribute defined outside init几乎无处不在。我只是想知道这种编码风格是否不受欢迎,如果是,那么“Pythonic 方式”是什么。

谢谢

4

5 回答 5

12

我这样做的方式是将其设置为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
于 2011-08-10T02:00:56.670 回答
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
于 2011-08-10T03:29:05.333 回答
1

如果您希望通过方法设置对象的特定属性,那么在初始化程序中总是可以使用它的原因。你可以使用self._hiTemp=NoneYou are already declaring it as private byleading _,所以用户会理解不要依赖它。

于 2011-08-10T02:02:51.570 回答
0

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

于 2011-08-10T02:00:10.990 回答
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
于 2011-08-10T02:01:44.470 回答