在哪里检查类的输入?

问题描述 投票:0回答:1

我应该在哪里检查类的输入。现在我将其放入

__init__
中,如下所示,但我不确定这是否正确。请参阅下面的示例。

import numpy as np

class MedianTwoSortedArrays:
    def __init__(self, sorted_array1, sorted_array2):
        
        # check inputs --------------------------------------------------------
        # check if input arrays are np.ndarray's
        if isinstance(sorted_array1, np.ndarray) == False or \
            isinstance(sorted_array2, np.ndarray) == False:
            raise Exception("Input arrays need to be sorted np.ndarray's")
            
        # check if input arrays are 1D
        if len(sorted_array1.shape) > 1 or len(sorted_array2.shape) > 1:
            raise Exception("Input arrays need to be 1D np.ndarray's")
        
        # check if input arrays are sorted - note that this is O(n + m)
        for ind in range(0, len(sorted_array1)-1, 1):
            if sorted_array1[ind] > sorted_array1[ind + 1]:
                raise Exception("Input arrays need to be sorted")
        
        # end of input checks--------------------------------------------------
        
        self.sorted_array1 = sorted_array1
        self.sorted_array2 = sorted_array2
python python-3.x validation
1个回答
3
投票

一般验证

您通常有两次机会检查传递给构造函数表达式的参数:

  • __new__
    方法中,例如使用 creation
  • __init__
    方法中,例如使用初始化

您通常应该使用

__init__
进行初始化和验证。 仅在需要其独特特性的情况下才使用
__new__
。 所以,您的支票位于“正确”的位置。

如果您还想验证初始化后对实例变量的任何赋值,您可能会发现这个问题及其答案很有帮助。

验证
__new__

__new__
的显着特征之一是在创建相关类的实例之前调用它。 事实上,__new__
的全部目的就是创建实例。  (这个实例然后被传递给
__init__
进行初始化。)

如其文档中所述,“

__new__()

主要旨在允许不可变类型(如 int、str 或 tuple)的子类自定义实例创建。”  因此,在子类化不可变类型时,您可能会在 __new__
 中包含验证逻辑,而不是 
__init__

考虑一个简单的示例,您想要创建

tuple

 的子类,称为 
Point2D
,它只允许创建包含 2 个 
float
 的实例(为此目的子类 
tuple
 是否明智:另一个问题):

class Point2D(tuple): def __new__(cls, x, y): if not isinstance(x, (int, float)) or not isinstance(y, (int, float)): error = "The coordinates of a 2D point have to be numbers" raise TypeError(error) return super().__new__(cls, (float(x), float(y)))
关于 

__new__

 的文档指出“它通常在自定义元类中被重写,以便自定义类创建。”  这个用例以及许多其他用例超出了这个问题的范围。  如果您仍然对 
__new__
__init__
 之间的差异感兴趣,您可能会发现这些来源很有帮助:

  • 何时使用 __new__
    __init__
  • Python(和 Python C API):__new__ 与 __init__
  • 在 __new__ 中使用 object.__new__ 有什么缺点?
异常类型

与主要问题无关:如果参数无效,则引发的异常的类型应尽可能具体。 对于你的情况:

© www.soinside.com 2019 - 2024. All rights reserved.