Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using unitialized variables in Python

Background: I have a class modeling a chip with registers, the chip has a bunch of registers, one of them is a high temperature limit for the built-in temperature sensor.

I have the following:

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

The reason that I don't declare self._hiTemp in the __init__ is because the user may not care about the temp-sensing capabilities of the chip. The user can be using the chip in different ways, and there is no meaning in giving this variable a meaningless value. However, if the user tries to use self._hiTemp without first setting it, the error of using undeclared variables is much easier to debug/backtrace than some obscure error like comparing numbers and None (or in some case even no errors at all).

This is all going fine until I start pylint, and of course I get W0201: Attribute defined outside init just about everywhere. I'm just wondering if this style of coding is frowned upon, and if so, what the "Pythonic way" is.

Thanks

like image 392
paper.cut Avatar asked Aug 10 '11 01:08

paper.cut


2 Answers

The way I'd do it is set it to None or some other sentinel value that doesn't occur 'in nature'. Then for operations that require it to be set, use an assert to fail fast in case the caller is trying to use your object inappropriately.

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
like image 53
Joe Holloway Avatar answered Oct 15 '22 09:10

Joe Holloway


Python's not Java, so don't write getters and setters like that. You can solve your problem like this

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
like image 42
John La Rooy Avatar answered Oct 15 '22 10:10

John La Rooy