gpt4 book ai didi

Pythonic 使用属性和异常

转载 作者:太空宇宙 更新时间:2023-11-04 04:46:31 24 4
gpt4 key购买 nike

<分区>

我有一个名为 Divider1 的类,它将分子除以分母,在初始化时设置:

class Divider1:
def __init__(self, numerator=0, denominator=1):
self.numerator = numerator
self.denominator = denominator

def divide(self):
return self.numerator / self.denominator

这个类很容易被不正确的初始化滥用,但直到真正发生划分时才立即清楚:

>>> x = Divider1('hello', 5)
>>> x.divide()
TypeError: unsupported operand type(s) for /: 'str' and 'int'

看来早点抛出异常对调试和维护是有好处的,所以我的下一个逻辑步骤是:

class Divider2:
def __init__(self, numerator=0, denominator=1):
try:
numerator = float(numerator)
except ValueError:
raise ValueError("Numerator must be numeric!")

try:
denominator = float(denominator)
except ValueError:
raise ValueError("Denominator must be numeric!")

if denominator == 0:
raise ValueError("Denominator must be non-zero!")

self.numerator = numerator
self.denominator = denominator

def divide(self):
return self.numerator / self.denominator

现在我们有了一些安全:

>>> x = Divider2('hello', 5)
ValueError: Numerator must be numeric!

我很清楚,初始化时出了什么问题,但初始化后仍然可以通过更改属性来滥用它:

>>> x = Divider2(10, 5)
>>> x.numerator = 'hello'
>>> x.divide()
TypeError: unsupported operand type(s) for /: 'str' and 'int'

我正在尝试找出处理这些问题的 Pythonic 方式。我可以将分子和分母命名为 _numerator_denominator,以表明它们应该被视为私有(private)的。

或者,我可以使用属性:

class Divider4:
def __init__(self, numerator=0, denominator=1):
self.numerator = numerator
self.denominator = denominator

@property
def numerator(self):
return self._numerator

@numerator.setter
def numerator(self, value):
try:
value = float(value)
except ValueError:
raise ValueError("Denominator must be numeric!")

self._numerator = value

@property
def denominator(self):
return self._denominator

@denominator.setter
def denominator(self, value):
try:
value = float(value)
except ValueError:
raise ValueError("Denominator must be numeric!")

if value == 0:
raise ValueError("Denominator must be non-zero!")

self._denominator = value

def divide(self):
return self.numerator / self.denominator

现在:

>>> x = Divider4(10, 5)
>>> x.numerator = 'hello'
ValueError: Numerator must be numeric!
>>> x = Divider4(10, 0)
ValueError: Denominator must be non-zero!

显然安全多了,我马上就知道了错误的原因,不管这个类是怎么用的——Divider不可能达到不可能的状态。但我必须编写更多行代码才能实现这一点,尤其是与 Divider1 相比。但我仍然认为应该始终达到这种安全性,尽管我还没有看到人们在编写 Python 代码时一直这样做。我是否以非预期的方式使用 Python?老是写这么繁琐的属性来保证安全是Pythonic吗?有什么时候应该或不应该这样做吗?

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com