我是 Python 中的 OOP 新手,假设我有一个执行简单计算的类:
class Calc:
def __init__(self, n1, n2):
self.n1 = n1
self.n2 = n2
def sum(self):
return self.n1 + self.n2
在这个简化的示例中,验证类属性的最佳方法是什么?例如,假设我希望 n1
和 n2
为 float
,这样我将构造函数定义为:
self.n1 = float(n1)
self.n2 = float(n2)
如果 n1
或 n2
为 None
,我会收到属性错误,因为 NoneType
不能是float
- 出于某种原因,我们在 Calc
类的构造函数中使用逻辑来捕获它感觉“错误”。
在创建类的实例来捕获上游之前,我是否需要某种验证逻辑?
有没有办法让我使用某种技术来动态验证,比如装饰器或属性注释?
如有任何建议,我们将不胜感激
最佳答案
这取决于您从何处获取数据以及您希望代码的简单程度。如果您希望此类绝对验证您不信任的输入数据,例如因为它直接来自用户输入,所以您需要进行显式验证:
class Calc:
def __init__(self, n1, n2):
if not all(isinstance(n, float) for n in (n1, n2)):
raise TypeError('All arguments are required to be floats')
self.n1 = n1
self.n2 = n2
在此基础上的下一个级别将是调试断言:
class Calc:
def __init__(self, n1, n2):
assert all(isinstance(n, float) for n in (n1, n2)), 'Float arguments required'
self.n1 = n1
self.n2 = n2
assert
statements can be disabled for performance gain ,因此不应被视为实际验证。但是,如果您的数据在此之前通过验证层,并且您通常希望参数为浮点型,那么这是很好且简洁的。它还兼作相当不错的 self 文档。
此后的下一步是 type annotations :
class Calc:
def __init__(self, n1: float, n2: float):
self.n1 = n1
self.n2 = n2
这更具可读性和自记录性,但在运行时不会执行任何操作。这取决于静态类型检查器来分析您的代码并指出明显的错误,例如:
Calc(input(), input())
此类问题可以通过 static type checker 来捕获并向您指出。 (因为 input
已知会返回字符串,这不符合类型提示),并且它们集成在大多数现代 IDE 中。
哪种策略最适合您和您的情况,由您决定。日常代码中会使用所有三种方法的不同组合。
关于python - Python 构造函数中的逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60887964/