Найти - Пользователи
Полная версия: Инициализация экземпляра класса в класе, инициализируется только один раз.
Начало » Python для новичков » Инициализация экземпляра класса в класе, инициализируется только один раз.
1
Jeck290
#!/usr/bin/python
# -*- coding: utf-8 -*-
class Book(object):
    def __init__(self):
        pass
class Chapter(object):
    def __init__(self):
        self.ID = 0
        self.CHAPTER = {}
        self.ITEM = Field()
    def set_id(self):
        self.ID += 1
        return self.ID
    def add_or_update(self, id=None, **kwargs):
        if id == None:
            print 1
            self.ITEM.set_update(**kwargs)
            self.CHAPTER[self.set_id()] = self.ITEM.get_field()
        else:
            print 2
            self.ITEM.set_update(**kwargs)
            self.CHAPTER[id] = self.ITEM.get_field()
    def update(self, id, **kwargs):
        # self.ITEM.set_update(**kwargs)
        self.CHAPTER[id] = self.ITEM.get_field()
    def get_chapter(self):
        return self.CHAPTER
class Field(object):
    def __init__(self, struct={'note': '', 'hours': 0}):
        self.FIELD = struct
    def get_field(self):
        return self.FIELD
    def get_all_key(self):
        return [x for x in self.FIELD]
    def set_update(self, **kwargs):
        self.FIELD.update(**kwargs)
if __name__ == '__main__':
    # f = Field()
    # print f.get_all_key()
    # f.set_update(note='dfdf', hours=3)
    # print f.get_field()
    c = Chapter()
    c.add_or_update(note='Ferst note1', hours=3)
    c.add_or_update(note='Ferst note2', hours=3)
    # c.update(id=2, note='BO', hours=4)
    print c.get_chapter()
Есть вот такой пример. Есть поле, которое должно являться словарем. Есть глава, в ней может быть много полей. Проблема в том что если в главу добавляешь два или более поля содержимое словаря всех полей становится одинаковым. В чем моя ошибка ? как сделать так что бы экземпляр класа поле был не один при инициализации ?
py.user.next
Jeck290
class Field(object):
    def __init__(self, struct={'note': '', 'hours': 0}):
        self.FIELD = struct

class Field(object):
    def __init__(self, struct=None):
        self.FIELD = struct or {'note': '', 'hours': 0}
Jeck290
Неа не работает ((
вывод остается таким же

{1: {'note': ‘Ferst note1’, ‘hours’: 3}}
{1: {'note': ‘Ferst note2’, ‘hours’: 3}, 2: {'note': ‘Ferst note2’, ‘hours’: 3}}

Получается сам клас Field инициализируется один раз а нужно много раз , как это реализовать ?
py.user.next
Напиши задание без учёта того, как оно реализуется. То есть что за книга, что за глава, что за поля главы, что должно быть в итоге?

Jeck290
Проблема в том что если в главу добавляешь два или более поля содержимое словаря всех полей становится одинаковым.
Потому что пишешь про какой-то “словарь всех полей”, когда словарём должно быть только поле.
Jeck290
Смотри должна быть книга (Book) в книге должны быть главы (Chapter) (их может быть много) в главах может быть строки (Field) (их тоже может быть много). Задание нужно написать структуру котрая состоит из класов Book , Chapter, Field , каждый клас реализует свою функциональность, например удаление , добавление , обнавление.

В класе Chapter нужно заполнять клас Field а потом просто генерируя словарь добавлять все в виде записи в словарь Chapter а с книгой будет идентично. Получается нужно составить композицию из трех классов Book->Chapter-Field
FishHook
class Field(object):
    def __init__(self, text):
        self.text = text
    def __str__(self):
        return self.text
class Chapter(object):
    def __init__(self, name):
        self.name = name
        self.fields = []
    def add(self, field):
        self.fields.append(field)
    def remove(self, field):
        self.fields.remove(field)
class Book(object):
    def __init__(self):
        self.chapters = {}
    def add(self, chapter):
        self.chapters.update({chapter.name: chapter})
    def remove(self, chapter_name):
        del self.chapters[chapter_name]
    def get(self, chapter_name):
        return self.chapters[chapter_name]
    def __getitem__(self, item):
        return self.get(item)
    def read(self):
        for chapter_name, chapter in self.chapters.iteritems():
            yield "\n"
            yield chapter_name + "\n\n"
            for field in chapter.fields:
                yield field
            yield "----" * 20
if __name__ == "__main__":
    book = Book()
    chapter = Chapter("ACT I")
    chapter.add(Field("FRANCISCO at his post. Enter to him BERNARDO"))
    chapter.add(Field("Who's there?"))
    chapter.add(Field("Nay, answer me: stand, and unfold yourself."))
    book.add(chapter)
    for r in book.read():
        print r
Jeck290
Спасибо.
py.user.next
Вариант без словарей, чисто на списках.
>>> class Book(list):
...     
...     def __init__(self, arg):
...         super(Book, self).__init__(arg)
...     
...     def add_chapter(self, chapter):
...         self.append(chapter)
...     
...     def remove_chapter(self, index):
...         del self[index]
...     
...     def update_chapter(self, index, chapter):
...         self[index] = chapter
...     
...     def __str__(self):
...         out = []
...         out.append('Book <')
...         out.append('|'.join(map(str, self)))
...         out.append('>')
...         return ''.join(out)
... 
>>> class Chapter(list):
...     
...     def __init__(self, arg):
...         super(Chapter, self).__init__(arg)
...     
...     def add_field(self, field):
...         self.append(field)
...     
...     def remove_field(self, index):
...         del self[index]
...     
...     def update_field(self, index, field):
...         self[index] = field
...     
...     def __str__(self):
...         out = []
...         out.append('Chapter <')
...         out.append(','.join(map(str, self)))
...         out.append('>')
...         return ''.join(out)
... 
>>> class Field(object):
...     
...     def __init__(self, value=None):
...         self.value = value
...     
...     def add_value(self, value):
...         self.value = value
...     
...     def remove_value(self):
...         self.value = None
...     
...     def __str__(self):
...         return str(self.value)
... 
>>> book = Book([Chapter([Field('a'), Field('b')]),
...              Chapter([Field('c'), Field('d')]),
...              Chapter([Field('e'), Field('f')])])
>>> 
>>> print book
Book <Chapter <a,b>|Chapter <c,d>|Chapter <e,f>>
>>>
Jeck290
Поясни , ты пишешь в инициализации super(Chapter, self).__init__(arg) , это значит каждый раз когда мы вызываем клас то создается экземпляр класса ? я прав или ошибаюсь
py.user.next
Jeck290
это значит каждый раз когда мы вызываем клас то создается экземпляр класса ?
Не, это обращение к другому __init__'у. Когда наследуешь один класс от другого, метод __init__ тоже наследуется. Но когда ты его определяешь в производном классе, то перекрываешь унаследованный. При создании экземпляра класса, задействуется тот __init__, который оказался последним. Поэтому в новом __init__'е нужно подняться в класс выше и взять __init__ оттуда, выполнить его, а потом уже продолжать новую инициализацию.

В данном случае там выполняются только __init__'ы базовых классов (то есть их можно было бы убрать), но сделаны они, чтобы ты мог в эти __init__'ы добавить что-то своё.
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