为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

拉莫斯之舞 2021-08-05 10:32:17
我有一个像下面这样的类: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。这是处理它的正确方法吗?但这也会导致对象状态不一致,因为应用程序将在运行时更改实例属性。我已经将数量作为发票的属性,以便更好地理解和可读性发票及其属性。只有当我们知道它的初始化/默认值时才使用类属性吗?
查看完整描述

3 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

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


查看完整回答
反对 回复 2021-08-05
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

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如果您想更好地支持打字,也可以使用。


查看完整回答
反对 回复 2021-08-05
  • 3 回答
  • 0 关注
  • 197 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号