bilokoniuk
bilokoniuk

Reputation: 1

How to use descriptors and __slots__ in Python at the same time

I am new to your community. Sorry for my English. I am interested in Python languages. Please help me understand descriptors. I don't know how to use descriptors and _slots_ in class Calendar at the same time. Here is an example of my code:

    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=".")

Upvotes: 0

Views: 454

Answers (1)

Noah Jackowitz
Noah Jackowitz

Reputation: 81

BLUF: if Calendar uses __slots__, it won't have a __dict__ attribute (that's the whole point of slots).

Per the python language reference (Notes on using __slots__):

__slots__ are implemented at the class level by creating descriptors (Implementing Descriptors) for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by __slots__; otherwise, the class attribute would overwrite the descriptor assignment.

There are two things you can do to fix the error and keep your code working (mainly) the same way.

  1. Don't use __slots__. They deny the creation of a __dict__, and you want the __dict__.
  2. (What I prefer), your class dateValue can own the underlying value and return it on __get__, instead of replacing the accessor with the value. your Calendar can keep its __slots__ and offload the additional values out of sight.

Upvotes: 1

Related Questions