Skip to main content
 首页 » 编程设计

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

2025年05月04日21oomusou

我有一个类如下:

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 不是 amount 的正确默认值。我应该能够区分金额值作为无与金额值根本没有设置。所以问题如下:

  1. 我们如何处理类属性没有正确默认值的情况?在上面的示例中,如果我从 init 中删除 self._amount = None,我会得到 self._amount 的 AttributeError 并且 self.amount 只会在我调用 invoice.amount = 5。这是处理它的正确方法吗?但这也会导致对象状态不一致,因为应用程序会在运行时更改实例属性。
  2. 为了更好地理解和阅读发票及其属性,我将金额保留为发票的属性。是否应该仅在我们知道其初始值/默认值时才使用类属性?

请您参考如下方法:

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 设置为无效值,但他们只会遇到他们想要的麻烦。我们都是成年人。