以正确的方式在 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/工具的缺点,还是我做错了?有没有更好的方法以 DRY 的方式实现相同的目标,没有警告,没有毫无意义的代码?

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

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

实际上,我认为您编写此类的方式确实不是编写python的正确方法,因为显式比IMPLICIT(在本地python解释器中键入"import zen")更好。

请记住,以_开头的变量表示"仅在知道自己在做什么时才使用"。

你正在做的事情在语法上没有任何错误。我会抑制这个特定的警告。

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

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)

最新更新