【问题标题】:How to use descriptors and __slots__ in Python at the same time如何在 Python 中同时使用描述符和 __slots__
【发布时间】:2021-04-08 17:32:29
【问题描述】:

我是您社区的新手。对不起我的英语不好。我对 Python 语言很感兴趣。请帮助我理解描述符。我不知道如何在日历类中同时使用描述符和 _slots_。这是我的代码示例:

    class dateValue:
    def __checkValue(value):
        if isinstance(value, int) or isinstance(value, float):
            return True
        return False

    def __set_name__(self, owner, name):
        self.__name = name

    def __get__(self, instance, owner):
        return instance.__dict__[self.__name]

    def __set__(self, instance, value):
        if dateValue.__checkValue(value):
            instance.__dict__[self.__name] = value
        else:
            raise ValueError("Неверный формат данных")

    def __delete__(self, instance):
        del instance.__dict__[self.__name]

    class Calendar:
    
        #__slots__ = ["day", "month", "year"]
    
        day = dateValue()
        month = dateValue()
        year = dateValue()
    
        def __init__(self, day=0, month=0, year=0):
            self.day = day
            self.month = month
            self.year = year

cal4 = Calendar()
cal4.day = 3
cal4.month = 3
cal4.year = 2023

day4 = cal4.day
month4 = cal4.month
year4 = cal4.year

print(day4, month4, year4, sep=".")

【问题讨论】:

  • 停止使用双下划线名称修饰。你为什么要这么做?
  • 无论如何,__slots__ 的全部意义在于实例没有__dict__。另外,__slots__ 通过 描述符工作,因此您不能使用同名的类变量。如果您只是创建一个空类但有这些插槽,然后查看vars(MyClass),您会发现它们在那里

标签: python descriptor slots


【解决方案1】:

BLUF:如果Calendar 使用__slots__,它将没有__dict__ 属性(这就是插槽的全部意义所在)。

根据 python 语言参考 (Notes on using __slots__):

__slots__ 在类级别通过为每个变量名创建描述符(实现描述符)来实现。因此,类属性不能用于为__slots__定义的实例变量设置默认值;否则,类属性将覆盖描述符分配。

您可以做两件事来修复错误并让您的代码(主要)以相同的方式工作。

  1. 不要使用__slots__。他们拒绝创建__dict__,而您想要__dict__
  2. (我更喜欢),您的类dateValue 可以拥有基础值并将其返回__get__,而不是用值替换访问器。您的 Calendar 可以保留其 __slots__ 并将附加值卸载到视线之外。

【讨论】:

    猜你喜欢
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多