Найти - Пользователи
Полная версия: Наследование класовых свойств
Начало » Python для новичков » Наследование класовых свойств
1
azazell00
В какой то момент мне понадобился базовый класс от которого можно будет унаследовать механизм присвоения уникальных айди, и механизм хранения всех обьектов.

Пишем абстрактный класс с двумя классовыми свойствами

from abc import ABCMeta, abstractmethod
class Basic(object):
    __metaclass__ = ABCMeta
    
    allInstances = set()
    nextId = 1
    
    def __init__(self, name):
        self.name = name
        self.idNumber = self.__class__.nextId
        self.__class__.nextId += 1
        self.allInstances.add(self)
    def __del__(self):
        self.allInstances.remove(self)
        
    
    @property
    def idNumber(self):
        return self._idNumber
    @idNumber.setter
    def idNumber(self, value):
        self._idNumber = value
        
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self, value):
        self._name = value
        
        
class Child1(Basic):
    pass
class Child2(Basic):*
    pass
    

посмотрим как будут вести себя наши обьекты


>>> from Basic import *
>>> child1_instance1 = Child1("child1_instance1")
>>> child1_instance2 = Child1("child1_instance2")
>>> child1_instance2 = Child2("child1_instance2")
>>> child2_instance2 = Child2("child2_instance2")

for i in child1_instance1.allInstances:
print i.name
print i.idNumber

>>> for i in child1_instance1.allInstances:
... print i.name
... print i.idNumber
...
child1_instance1
1
child1_instance2
2
child2_instance2
2
child1_instance2
1

и тут я невольно задумался насколько хорошо я понимаю модель данных питона. Получается что для дочкрних классов отдельно были созданы класовые свойства для nextId но allInstances одна на всех и хранит обьекты всех дочерних классов.
Может кто нибудь обьяснить почему так происходит?

Добиться нужного повведения мне удалось создав свой мета класс унаследованный от ABCMeta

from abc import ABCMeta
class MyMeta(ABCMeta):
    def __init__(cls, name, bases, dct):
        super(MyMeta, cls).__init__(name, bases, dct)
        cls.allInstances = set()

Может мне стоит все классовые свойства и весь механизм перенести в MyMeta?
azazell00
Админы, может перенесите тему в раздел “Для новичков”?
Rodegast
> Получается что для дочкрних классов отдельно были созданы класовые свойства для nextId но allInstances одна на всех и хранит обьекты всех дочерних классов. Может кто нибудь обьяснить почему так происходит?

А чему ты удивляешся? У тебя nextId и allInstances - атрибуты класса т.е. они общие для всех его экземпляров, а idNumber это обычный атрибут.
azazell00
Rodegast
А чему ты удивляешся? У тебя nextId и allInstances - атрибуты класса т.е. они общие для всех его экземпляров, а idNumber это обычный атрибут.

Это да, но nextId для каждого дочернего класса отдельный иначе все айдишники были бы разные. А так для каждого подкласса ведется отсчет отдельно. И при этом для всех подклассов обьекты хранятся в одном сете.
FishHook
Не очень понятен ваш вопрос.
У вас код не соответствует выводу
вот код
>>> child1_instance1 = Child1("child1_instance1“)
>>> child1_instance2 = Child1(”child1_instance2“)
>>> child1_instance2 = Child2(”child1_instance2“)
>>> child2_instance2 = Child2(”child2_instance2")

вот вывод
child1_instance1
child1_instance2
child2_instance2
child1_instance2

Вы где-то чего-то напутали кажется
Rodegast
self.idNumber = self.__class__.nextId
self.__class__.nextId += 1
В данном случае self.__class__ ссылается не на базовый класс, а на его потомка т.е. у каждого дочернего класса создаётся отдельный атрибут nextId. Если он должен быть только у базового класса, то надо писать Basic.nextId += 1
azazell00
Спасибо за ответы
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB