猿问

在 Python 中处理具有未知默认值的类属性

我有一个像下面这样的类:


class Invoice

    def __init__(self, invoice_id):

        self.invoice_id = invoice_id

        self._amount = None


    @property

    def amount(self):

        return self._amount


    @amount.setter

    def amount(self, amount):

        self._amount = amount

在上面的示例中,每当我尝试在不设置其值的情况下获取发票金额时,我都会得到一个 None,如下所示:


invoice = Invoice(invoice_id='asdf234')

invoice.amount

>> None

但在这种情况下, None 不是金额的正确默认值。我应该能够区分金额值是 None 还是根本没有设置金额值。所以问题如下:


我们如何处理类属性没有正确默认值的情况?在上面的例子中,如果我self._amount = None从 init 中删除,我会得到 self._amount 的 AttributeError 并且 self.amount 只有在我调用之后才会返回一个有效值invoice.amount = 5。这是处理它的正确方法吗?但这也会导致对象状态不一致,因为应用程序将在运行时更改实例属性。

我已经将数量作为发票的属性,以便更好地理解和可读性发票及其属性。只有当我们知道它的初始化/默认值时才使用类属性吗?


拉莫斯之舞
浏览 198回答 3
3回答

忽然笑

None通常用于缺少值,但有时您需要它实际上是一个允许的值。如果您希望能够区分None和未设置的值,只需为此目的定义您自己的单例。class Undefined:    __str__ = __repr__ = lambda self: "Undefined"Undefined = Undefined()class Invoice    def __init__(self, invoice_id):        self.invoice_id = invoice_id        self._amount = Undefined    @property    def amount(self):        return self._amount    @amount.setter    def amount(self, amount):        if amount is Undefined:            raise ValueError("amount must be an actual value")        self._amount = amount当然,您现在可能需要Undefined在其他方法中进行测试,以确保在正确初始化实例之前它们没有被使用。更好的方法可能是在初始化期间设置属性并要求将其值传递给__init__(). 这样,您就可以避免Invoice处于无效(未完全初始化)状态。有人仍然可以设置_amount为无效值,但他们只会遇到他们所要求的麻烦。我们这里都是成年人。

人到中年有点甜

property在这种情况下不要使用 a 。你的 getter 和 setter除了 return 和 set the value 什么都不做。只需使用普通属性即可。如果您以后想要控制访问权限,您可以稍后添加该属性,而无需更改类的接口!至于处理未设置的值,只需创建自己的对象来表示从未设置过的值。它可以很简单:>>> NOT_SET = object()>>> class Invoice:...     def __init__(self, invoice_id):...         self.invoice_id = invoice_id...         self.amount = NOT_SET...>>> inv = Invoice(42)>>> if inv.amount is NOT_SET:...     inv.amount = 1...enum如果您想更好地支持打字,也可以使用。
随时随地看视频慕课网APP

相关分类

Python
我要回答