背景:我有一个用寄存器建模芯片的类,芯片有一堆寄存器,其中一个是内置温度传感器的高温限制。
我有以下内容:
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方式”是什么。
由于
答案 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