【问题标题】:Best practice python init check最佳实践 python 初始化检查
【发布时间】:2017-04-07 11:56:27
【问题描述】:

在初始化 python 类时,初始化属性和检查提供的参数的最佳方法是什么?假设__init__() 中有多个参数,其中一些必须遵守一定的规则。还需要为其中一些设置 setter 和 getter。我可以从下面想到选项。你觉得它怎么样?有没有更好的选择?

选项:初始化属性None 并调用执行检查的setter。

class A(object):
    def __init__(self, p1=None, ..., pn=None):
        self._p1 = None
        ...
        self._pn = None

        if p1 is not None:
            self.p1 = p1
        ...
        if pn is not None:
            self.pn = pn

    @p1.setter
    def p1(self, p1):
        # If p1 is int we can just take it
        if isinstance(p1, int):
            self._p1 = p1
        # If p1 is str we have to obtain it differently
        elif isinstance(p1, str):
            self._p1 = self._gen_some_p_from_str(p1)
        else:
            raise Exception('Incorrect p1 type provided.')
    ...
    @pn.setter
    def pn(self, pn):
        # If pn instance of SomeOtherClass it should be also great
        if isinstance(pn, SomeOtherClass):
            if pn.great():
                self._pn = pn
            else:
                raise exception('pn not great')
        # pn can be also str, and then we should get it
        elif isinstance(pn, str):
             self._pn = self._get_some_other_p_from_str(pn)
        else:
            raise Exception('Incorrect pn type provided.')

【问题讨论】:

  • 摆脱支票。编写适当的文档/文档字符串。从这里是垃圾进 -> 垃圾出。

标签: python class init


【解决方案1】:

如果您需要对每个分配运行验证,属性是您的选择。

请记住,当您有许多分配时(例如在循环中),这可能会导致性能问题。

您的问题可以通过仅在类启动时验证输入来解决,您最好在您的类上有一个 cleanvalidate 方法,然后在 __init__ 函数的末尾调用它。

使用此方法,您可以在需要时调用您的clean 方法,并省略性能比验证更重要的调用(这就是django forms 的工作原理)。

在您的情况下,您正在尝试进行重载/调度,请查看docs

【讨论】:

  • 感谢您的回答,但您能详细说明一下吗?我需要针对不同参数的不同验证函数,我在想是否可以删除 __init__() 中的 if 并同时保留 _*
  • 但是每次你调用pq=something你的验证都会应用,这在多个属性上运行时可能会很昂贵,多次(比如在for循环中)。你可以定义一个clean 方法,这样你就可以控制验证发生的时间——如果这更适合你的情况,那么你,
猜你喜欢
  • 1970-01-01
  • 2010-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多