以正确的方式在setter和构造函数中重用验证逻辑

时间:2014-11-22 07:00:16

标签: python pycharm

我有一个带有自定义setter属性的类来执行验证。 我希望能够将属性作为构造函数参数传递, 并从构造函数中调用setter以重用验证逻辑:

class Part(object):
    def __init__(self, pn):
        # self._pn = None
        self.pn = pn

    @property
    def pn(self):
        return self._pn

    @pn.setter
    def pn(self, value):
        if type(value) != str:
            raise Exception("Part number must be a string")
        self._pn = value  # warning here

在最后一行,PyCharm发出警告:

Instance attribute _pn defined outside __init__ 

如果我在构造函数中取消注释self._pn = None,则警告消失, 但我不喜欢它,因为它是无意义的代码:如果引发异常, 无论如何都不会创建一个对象,那么设置初始值的点是什么?

这是PyCharm /工具的缺点,还是我做错了? 有没有更好的方法来实现相同的,没有警告,没有无意义的代码,干嘛?

3 个答案:

答案 0 :(得分:1)

PyCharm在这里没错。警告告诉您,您正在运行时在对象上创建变量。

此警告的目的是提醒您可能拼错了变量的名称,因为这是编写python时可能发生的事情。

我实际上认为你编写这个类的方式确实不是编写python的正确方法,因为EXPLICIT比IMPLICIT更好(在你的本地python解释器中输入“import zen”)。

请记住,以_开头的变量意味着“只有在您知道自己在做什么的情况下才会使用。”

答案 1 :(得分:0)

这具有相同的行为,不应触发警告。

class Part(object):
    def __init__(self, pn):
        self.pn = pn

    @property
    def pn(self):
        return getattr(self, '_pn')

    @pn.setter
    def pn(self, value):
        if type(value) != str:
            raise Exception("Part number must be a string")
        setattr(self, '_pn', value)

答案 2 :(得分:0)

你所做的事情在句法上没有任何错误。我suppress发出了这个警告。