Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 29, 2015 18:24:39

azazell00
Зарегистрирован: 2014-10-26
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Наследование класовых свойств

В какой то момент мне понадобился базовый класс от которого можно будет унаследовать механизм присвоения уникальных айди, и механизм хранения всех обьектов.

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

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?

Офлайн

#2 Сен. 29, 2015 22:06:31

azazell00
Зарегистрирован: 2014-10-26
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Наследование класовых свойств

Админы, может перенесите тему в раздел “Для новичков”?

Офлайн

#3 Сен. 29, 2015 22:28:41

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2843
Репутация: +  186  -
Профиль   Отправить e-mail  

Наследование класовых свойств

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

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



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#4 Сен. 30, 2015 09:58:44

azazell00
Зарегистрирован: 2014-10-26
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Наследование класовых свойств

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

Это да, но nextId для каждого дочернего класса отдельный иначе все айдишники были бы разные. А так для каждого подкласса ведется отсчет отдельно. И при этом для всех подклассов обьекты хранятся в одном сете.

Офлайн

#5 Сен. 30, 2015 10:02:39

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Наследование класовых свойств

Не очень понятен ваш вопрос.
У вас код не соответствует выводу
вот код
>>> 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

Вы где-то чего-то напутали кажется



Офлайн

#6 Сен. 30, 2015 10:49:36

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2843
Репутация: +  186  -
Профиль   Отправить e-mail  

Наследование класовых свойств

self.idNumber = self.__class__.nextId
self.__class__.nextId += 1
В данном случае self.__class__ ссылается не на базовый класс, а на его потомка т.е. у каждого дочернего класса создаётся отдельный атрибут nextId. Если он должен быть только у базового класса, то надо писать Basic.nextId += 1



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Отредактировано Rodegast (Сен. 30, 2015 10:52:28)

Офлайн

#7 Сен. 30, 2015 14:14:37

azazell00
Зарегистрирован: 2014-10-26
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Наследование класовых свойств

Спасибо за ответы

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version