Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
2 / 1 / 1
Регистрация: 16.08.2019
Сообщений: 48

Наследование класса

05.12.2019, 23:42. Показов 2902. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть код:
Python
1
2
3
4
5
6
7
8
9
10
class Account:
    def __init__(self):
        self.bank = Bank()
        self.money = 500
 
class Bank:
    def __init__(self):
        self.balance = #данные атрибута money класса Account
 
acc = Account()
self.bank = Bank() нужен, чтобы использовать конструкцию acc.bank.balance.
Мне нужно, чтобы в классе Bank в атрибуте self.balance наследовались данные атрибута self.money класса Account.
Но в классе Bank нельзя взаимодействовать с классом Account, т.к. в нем инициализируется экземпляр класса Bank. И если так сделать, то он уходит в рекурсию.
Уже голову всю сломал не знаю как сделать...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.12.2019, 23:42
Ответы с готовыми решениями:

Наследование переменной класса
Здравствуйте! Я только учу Python и сейчас вот разбираюсь с наследованием классов. Подскажите пожалуйста почему и как наследовать...

Наследование класса python
Доброго времени суток. Недавно начал пробовать писать на python, сделал небольшой плоттер графиков, но теперь мне для удобного формата окна...

Задача на наследование с использованием абстрактного класса
Разработать базовый класс Commodity, описывающий товар. Поля: название товара; цена в рублях. Конструкторы: по умолчанию; с...

12
1732 / 970 / 199
Регистрация: 22.02.2018
Сообщений: 2,693
Записей в блоге: 6
06.12.2019, 07:30
FroDK, Как я понимаю Account это счет в банке. Но класс Bank, это не конкретный банк , а множество банков. Запись Bank() создает какой то экземпляр банка, мы не знаем какого.
В результате что получаем. Что экземпляр счета, а именно конкретный счет асс имеет в качестве свойства (атрибута) принадлежность к некоторому банку. Но мы не знаем к какому, так как не знаем параметров этого банка, например его название. Поэтому мы получаем безликий счет, принадлежащий не известно какому банку.
self.balance это баланс некоторого банка.
Не понятно, что у Вас подразумевается под Account, счет в банке или счет банка в центральном банке.
Алгоритм размытый. Поэтому вообще не понятно, что Вы хотите.
Цитата Сообщение от FroDK Посмотреть сообщение
Мне нужно, чтобы в классе Bank в атрибуте self.balance наследовались данные атрибута self.money класса Account.
self.balance это баланс некоторого банка, у Вас не указывается какого.
Опишите задачу, а так не понятно , что Вы хотите. Не возможно наследовать неизвестно что, не известно куда.
Класс описывает не конкретный объект а множество объектов.
Что бы разобраться, дайте всем создаваемым экземплярам Ваших классов конкретные имена, а возможно и еще другие свойства (атрибуты).
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7391 / 4818 / 1246
Регистрация: 30.03.2015
Сообщений: 13,693
Записей в блоге: 29
06.12.2019, 07:48
FroDK, счет не может содержать банк, это банк содержит счета, не верно строите структуру потому и голова сломана.

У класса Банк если и может быть пункт баланс -то это сумма всех счетов, а не 1, согласен? а скорее у него должен быть метод получения аккаунта по ид или имени, а уже у аккаунта берем баланс.

Проще говоря Аккаунт и Банк - не родственники, Банк содержит аккаунты.
0
1732 / 970 / 199
Регистрация: 22.02.2018
Сообщений: 2,693
Записей в блоге: 6
06.12.2019, 08:46
FroDK, Если Вы пишете программу для конкретного банка, и хотите это делать используя класс Bank, то создайте экземпляр класса, который будет являться Вашим банком
bnk = Bank()
и уже с ним работайте. Но для работы с банком нужно в классе описать его свойства и методы, то есть атрибуты. в качестве свойства банка можно задать множество счетов (лучше в виде словаря), как экземпляров класса Account. Определить в классе Bank методы открытия и закрытия счетов, поступления на них денег и снятие денег, и т.д. Тоесть в классах Bank и Account нужно описать реальные свойства и методы для экземпляров этих классов.

Добавлено через 9 минут
Кстати общие принципы построения аналогичны телефонной книге которую я написал. Но код у меня получился громоздким из-за использования графики для построения формы. Здесь можно провести аналогию банка с телефонной книгой, а счета с записями телефонов в книге.
Кликните здесь для просмотра всего текста
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# файл *.pyw (расширение .pyw необходимо для подавления окна DOS)
 
from tkinter import *                              # импорт объектов для графики
from tkinter.messagebox import *                   # импорт объектов для диалоговых окон
import shelve                                      # импорт модуля для работы с базой данных 
 
class PhoneBook:
    # класс Телефонная книга
    def __init__(self, nameBook, dicRec={}):
        # метод инициализации атрибутов экземпляров класса  и передача в метод значений для атрибутов
        self.nameBook = nameBook                   # инициализация атрибута Имя книги
        self.dicRec = dicRec                       # перечень записей в виде словаря, по умолчанию пустой
    def loadBook(self):
        # загрузка записей из базы данных
        db = shelve.open(self.nameBook)            # открытие базы данных (имя берется из атрибута nameBook экземпляра класса)
        self.dicRec = dict(db.items())             # загрузка записей из базы данных в атрибут dicRec экземпляра класса (в словарь экземпляра класса)
        db.close()                                 # закрытие базы данных
    def saveBook(self):
        # сохранение записей в базе данных
        db = shelve.open(self.nameBook)            # открытие базы данных
        for (key, record) in self.dicRec.items():  # запись содержимого из 
            db[key] = record                       # словаря экземпляра класса в базу данных
        db.close()                                 # закрытие базы данных
 
class PhoneRec:
    # класс Запись
    def __init__(self, keyRec, char, label, phone, familyName, comment, delR=''):
        # инициализация атрибутов экземпляров класса
        self.keyRec = keyRec                       # ключ записи
        self.char = char                           # буква, на странице которой находится запись
        self.label = label                         # метка, к чему относится запись
        self.phone = phone                         # телефон
        self.familyName = familyName               # Ф.И.О.
        self.comment = comment                     # комментарий
        self.delR = delR                           # служебное поле для пометки записи:
                                                   # ''- видимая, 'с' - скрытая, 'у' - удаляемая
 
fieldnamesRec = ('keyRec', 'char', 'label', 'phone', 'familyName', 'comment', 'delR')  # кортеж имен полей в записи
activCh = 'А'                                      # буква, актмвная на текущий момент
typeRec = ''                                       # тип выводимых на экран записей, '' - открытые, "с" - скрытые
dicRem = {}                                        # словарь оставшихся не выведенными записей
 
def onDeleteRequest():
#    print('Got wm delete') # щелчок на кнопке X в окне: можно отменить или перехватить
    saveRec()
    window.destroy()         # возбудит событие <Destroy>
#def doRootDestroy(event):
#    print('Got event <destroy>') # для каждого виджета в корневом окне
def makeWidgets():
    # создание графической формы
    global entriesRec, entRec, lab1, alph          # перечень глобальных переменных, которые будут использоваться и за пределами функции
    entRec = {}                                    # словарь, в который будут заносится объекты ввода entFind (поиск) и entKeyRec (ключ)
    window = Tk()                                  # создание главного окна
    window.title('Телефоны')                       # заголовок окна
    window.geometry('1260x600+0+0')                # размеры окна
#    window.bind('<Destroy>', doRootDestroy)              # для корневого и дочерних 
    window.protocol('WM_DELETE_WINDOW', onDeleteRequest) # на кнопке X окна (перехватывает нажатие кнопки Х)
    form1 = Frame(window)                          # создание внутри окна window контейнера form1
    form1.pack()
    lab1 = Label(form1, text=activCh, fg="#eee", bg="#333", width=5)  # метка, показывающая
    lab1.pack(side=LEFT)                                              # активную букву
    Label(form1, text='  ', width=30).pack(side=LEFT)                 # вспомагательная пустая метка для улучшения расположения
    alph = ["А", "Б", "В", "Г", "Д", "Е", "Ж", "З", "И", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", 
            "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Э", "Ю", "Я"]         # список букв
    for i in range(len(alph)):                     # создание кнопок с буквами
        Button(form1, text=alph[i], command=(lambda x=alph[i]: fetchChr(x))).pack(side=LEFT)
    ent = Entry(form1, width=27)                   # поле ввода для поиска
    ent.pack(side=LEFT)
    entRec['entFind'] = ent                        # поместить объект поля ввода в словарь entRec
    Button(form1, text="Поиск", command=fetchFind).pack(side=LEFT)     # создание кнопки Поиск
 
    form2 = Frame(window)                          # создание внутри окна window контейнера form2
    form2.pack()
    entriesRec = {}                # словарь, для занесения в него объектов Entry ячеек таблицы ввода записей
    fieldnamesRecCyr = ('№№', 'Буква', 'Метка', 'Телефон', 'ФИО', 'Комментарий', 'тип')  # кортеж имен полей на руском
    for (ix, label) in enumerate(fieldnamesRecCyr): # создание надписей заголовков столбцов таблицы
        lab = Label(form2, text=label)
        lab.grid(row=2, column=ix)
    for i in range(1, 26):         # создаются ячейки таблицы для ввода записей
        for (ix, label) in enumerate(fieldnamesRec):
            if label == 'keyRec' or label == 'char' or label == 'delR':  # выделяются столбцы, которые потом будут иметь особый режим доступа
                ent = Entry(form2, state='normal', width=6)
            else:
                ent = Entry(form2, width=40)
            ent.grid(row=i+2, column=ix)
            entriesRec[label+str(i)] = ent   # объекты ячеек таблицы заносятся в словарь, причем к имени 
                                             # столбца ячейки добавляется номер строки, 
                                             # тем самым однозначно определяются координаты ячейки,
                                             # что бы к ней обращаться
    form3 = Frame(window)                            # создание внутри окна window контейнера form3
    form3.pack()
    Button(window, text="Следующая страница", command=fetchNext).pack()  # кнопка Следующая страница
    Label(window, text='      ', width=10).pack(side=LEFT)       # вспомогательная пустая метка
    labKeyRec = Label(window, text='№').pack(side=LEFT)     # надпись перед полем ввода номера ключа
    ent = Entry(window, width=10)                                # поле ввода номера ключа
    ent.pack(side=LEFT)
    entRec['entKeyRec'] = ent             # занесение объекта поле ввода номера ключа в словарь entRec
    Button(window, text="Скрыть", command=hideRec).pack(side=LEFT)             # кнопка Скрыть (запись)
    Button(window, text="Показать скрытые", command=fetchHide).pack(side=LEFT) # кнопка Показать скрытые
    Button(window, text="Открыть", command=openRec).pack(side=LEFT)            # кнопка Открыть (запись)
    Label(window, text=' ', width=5).pack(side=LEFT)                           # вспомогательная пустая метка
    Button(window, text="Удалить", command=delKeyRec).pack(side=LEFT)          # кнопка удалить (запись)
    Label(window, text='      ', width=30).pack(side=LEFT)                     # вспомогательная пустая метка
    btns = Button(window, text="Сохранить", command=interSave).pack(side=LEFT)   # кнопка Сохранить (страницу)
    Label(window, text='      ', width=20).pack(side=LEFT)                     # вспомогательная пустая метка
    Button(window, text="Выход", command=fin).pack(side=LEFT)                  # кнопка Выход (из программы)
    return window                                              # функция makeWidgets возвращает окно window
 
def clear_sheet():
    # очистка листа
    for i in range(1, 26):
        for field in fieldnamesRec:
            if field == 'keyRec' or field == 'delR':              # для очистки полей keyRec и delR,
                entriesRec[field+str(i)].config(state='normal')   # нужно открыть их для записи
                entriesRec[field+str(i)].delete(0, END)
                entriesRec[field+str(i)].config(state='readonly')
            else:
                entriesRec[field+str(i)].delete(0, END)         # очистка остальных полей
def fetchChr(ch):
    # выбрать записи на букву ch
    global activCh, typeRec, lab1
    saveRec()                      # предварительно сохранить предыдущую страницу
    typeRec = ''                   # выбор для буквы делать только из открытых записей
    activCh = ch                   # сделать ch текущей буквой
    lab1.config(text=activCh)      # написать, для какой буквы выводятся записи
    dicRecChr = {}                 # словарь, в который помещаются выбранные записи
    for key in t1.dicRec.keys():      # выбор записей и помещение их в словарь
        if t1.dicRec[key].char == ch:
            dicRecChr[key] = t1.dicRec[key]
    fetch(dicRecChr)                        # вывод записей в таблицу формы
def interSave():
    # # принудительное сохранение текущей страницы и повторный вывод записей для этой буквы начиная с первой страницы
    fetchChr(activCh)
def fetchHide():
    # вывод скрытых записей
    global typeRec, lab1
    saveRec()
    lab1.config(text='скр')
    typeRec = 'с'
    fetch(t1.dicRec)
def fetch(dicR):
    # вывод записей из заданнго словаря
    global dicRem                        # словарь записей, оставшихся не выведенными
    clear_sheet()                        # очистка таблицы
    count = 1                            # счетчик показывающий номер строки, в которую выводится запись
    dicRe = dicR.copy()                  # словарь, ведущий учет записей, которые еще не выведены
    while count <= 25 and len(dicRe):    # в цикле, заполнение строк таблицы записями
        for key in dicR.keys():            # в цикле вывод записи удовлетворяющей условию
            if dicR[key].delR == typeRec:
                record = dicR[key]                   # запись для вывода
                for field in fieldnamesRec:          # в цикле последовательное заполнение полей в строке
                    if field == 'keyRec' or field == 'delR':    # поля, которые необходимо открыть для записи
                        entriesRec[field+str(count)].config(state='normal')
                        entriesRec[field+str(count)].insert(0, getattr(record, field))
                        entriesRec[field+str(count)].config(state='readonly')
                    else:
                        entriesRec[field+str(count)].insert(0, getattr(record, field))  # все остальные поля
                count += 1         # переход к следующей строке таблицы
                dicRe.pop(key)     # удаление записи, которая выведена из словаря учета оставшихся записей           
                if count > 25:     # если все строки таблицы заполнены, то выход из цикла while
                    break
            else:
                dicRe.pop(key) # удаление из словаря учета записи, которая не удовлетворяет условию вывода в таблицу
    dicRem = dicRe.copy()      # словарь записей, оставшихся не выведенными
 
def fetchNext():
    # вывод на следующей странице записей, оставшихся не выведенными
    saveRec()
    fetch(dicRem)
 
def delKeyRec():
    # физическое удаление из базы данных записи, которая указана в ячейке entKeyRec
    key = entRec['entKeyRec'].get()  # из ячейки entKeyRec берется ключ записи для удаления
    if askyesno('Подтверждение', 'Удалить запись без возможности востановления?'):  # подтверждение на удаление
        del t1.dicRec[key]               # запись удаляется из динамического словаря t1.dicRec
        db = shelve.open(t1.nameBook)    # открывается база данных
        del db[key]                      # указанная запись физически удаляется из базы данных
        db.close()                       # база данных закрывается
        for i in range(1, 26): # ищется строка таблицы с этой записью, и помечается как удаленная, 
            if entriesRec['keyRec'+str(i)].get() == key:         # что бы потом при сохранении страницы,
                entriesRec['delR'+str(i)].config(state='normal') # она не была вновь занесена в базу данных
                entriesRec['delR'+str(i)].insert(0, 'у')
                entriesRec['delR'+str(i)].config(state='readonly')
        entRec['entKeyRec'].delete(0, END)            # очищается ячейка, содержащая номер удаляемой записи
    else:
        showinfo('Отмена', 'Удаление записи отменено')   # удаление отменено
def hideRec():
    # пометить как скрытую
    key = entRec['entKeyRec'].get()  # из ячейки entKeyRec берется ключ записи для сокрытия
    for i in range(1, 26):           # ищется строка таблицы с этой записью, и помечается как скрытая
        if entriesRec['keyRec'+str(i)].get() == key:
            entriesRec['delR'+str(i)].config(state='normal')
            entriesRec['delR'+str(i)].insert(0, 'с')
            entriesRec['delR'+str(i)].config(state='readonly')
    entRec['entKeyRec'].delete(0, END)           # очищается ячейка, содержащая номер скрываемой записи записи
def openRec():
    # открыть скрытую запись
    key = entRec['entKeyRec'].get()   # из ячейки entKeyRec берется ключ записи для открытия
    for i in range(1, 26):            # ищется строка таблицы с этой записью, и помечается как открытая
        if entriesRec['keyRec'+str(i)].get() == key:
            entriesRec['delR'+str(i)].config(state='normal')
            entriesRec['delR'+str(i)].delete(0, END)
            entriesRec['delR'+str(i)].insert(0, '')
            entriesRec['delR'+str(i)].config(state='readonly')
    entRec['entKeyRec'].delete(0, END)           # очищается ячейка, содержащая номер открываемой записи 
 
def fetchFind():
    # поиск записей по заданной строке
    global lab1
    saveRec()
    clear_sheet()
    lab1.config(text='поиск')      # сигнализирует о режиме поиска
    strF = entRec['entFind'].get() # строка для поиска берется из ячейки entFind
    dicFind = {}                   # словарь, для занесения в него найденных записей
    for key in t1.dicRec.keys():   # в тлефонном справочнике ищутся записи содержащие искомую строку
        record = t1.dicRec[key]
        for field in fieldnamesRec:
            if (field != 'keyRec' and field != 'char' and field != 'delR' and # поиск в полях, за исключением перечисленных
                getattr(record, field).find(strF) != -1):
                dicFind[key] = record
                break
    fetch(dicFind)                  # вывод найденных записей
def saveRec():
    # сохранение текущей страницы
    global typeRec
    for i in range(1, 26):       # просмотр строк и при наличии хотя бы в одном поле строки данных, сохранение ее
        key = entriesRec['keyRec'+str(i)].get() # проверка наличия в строке ключа
        if entriesRec['delR'+str(i)].get() == 'у': # записи помеченные как удаленные пропускаются
            continue
        elif key:                # иначе, если запись не удаленная и с ключом, то она перезаписывается
            record = t1.dicRec[key]
            for field in fieldnamesRec:
                setattr(record, field, entriesRec[field+str(i)].get())
            t1.dicRec[key] = record
        else: # иначе, если в строке нет ключа, но в одном из полей есть данные, то создается запись-экземпляр
            existRec = False                                               # и помещается а словарь t1.dicRec
            for field in fieldnamesRec:
                if entriesRec[field+str(i)].get(): existRec = True # Если существует запись в поле на этой строке
            if existRec:     # если данные в строке существуют, то создается запись
                if entriesRec['char'+str(i)].get():  # если поле буквы не пусто, то в запись заносится эта буква
                    char = entriesRec['char'+str(i)].get()
                else:              # иначе в запись заносится буква, являющаяся на данный момент активной
                    char = activCh
                label = entriesRec['label'+str(i)].get()             # заполняются переменные
                phone = entriesRec['phone'+str(i)].get()             # для формирования записи
                familyName = entriesRec['familyName'+str(i)].get()
                comment = entriesRec['comment'+str(i)].get()
                if len(t1.dicRec)>0: # если телефонный справочник не пуст, то к максимальному значению ключа 
                    L = sorted(t1.dicRec.items(), key=lambda item: int(item[0]))  # прибавляется единица
                    keyRec = str(int(L[-1][0]) + 1)
                else:        # иначе записи присваивается ключ равный 1
                    keyRec = "1"
                record = PhoneRec(keyRec, char, label, phone, familyName, comment) # создается запись, экземпляр класса PhoneRec
                t1.dicRec[keyRec] = record     #  и записывается в словарь t1.dicRec
    t1.saveBook()  # словарь t1.dicRec сохраняется во внешней базе данных "Телефоны"
 
def fin():            # сохранение перед закрытием окна
    saveRec()
    window.destroy()
 
if __name__ == '__main__':
 
    t1 = PhoneBook("Телефоны")   # создание экземпляра класса PhoneBook
    t1.loadBook()                # загрузка внешней базы данных в словарь t1.dicRec,
                                 # с которым в дальнейшем будет производится вся работа, 
                                 # перед выгрузкой потом назад в базу данных
    window = makeWidgets()       # создание формы
    fetchChr('А')                # вывод в качестве стартовой страницу с буквой "А"
    window.mainloop()            # передача управления форме

Если не использовать графику, то код становиться достаточно простым.
Пример я привел, что бы показать общий подход в использовании двух классов. Первый как контейнер, второй как содержимое этого контейнера.

Добавлено через 14 минут
Правильнее выразится не класс как контейнер, а экземпляр класса как контейнер. А экземпляры второго класса, как содержимое экземпляра-контейнера.
0
2 / 1 / 1
Регистрация: 16.08.2019
Сообщений: 48
06.12.2019, 12:01  [ТС]
Viktorrus, Просто мне нужно сделать конструкцию вида: account.bank.balance. Поэтому и создал 2 класса.
0
1732 / 970 / 199
Регистрация: 22.02.2018
Сообщений: 2,693
Записей в блоге: 6
06.12.2019, 16:08
Цитата Сообщение от FroDK Посмотреть сообщение
Просто мне нужно сделать конструкцию вида: account.bank.balance
account не есть Account.
account не определенная переменная. Видимо Вы имели ввиду acc, что является экземпляром класса Account.
acc.bank является экземпляром класса Bank, но о котором мы ничего не знаем, так как этот экземпляр не имеет никаких атрибутов, кроме атрибута balance. То есть acc.bank это некоторый банк, который имеет некоторый баланс. Как правильно заметил Welemir1
Цитата Сообщение от Welemir1 Посмотреть сообщение
если и может быть пункт баланс -то это сумма всех счетов, а не 1
Поэтому мы не можем наследовать от экземпляра класса Account, каковым является acc, значение атрибута money.
Не может балансу банка присваиваться значение являющееся свойством счета из этого банка. Такое возможно только в том случае, если в этом банке открыт всего лишь один счет. Но это бессмысленно. Такую организацию нельзя назвать банком, у которой открыт всего лишь один счет.
Поэтому квалифицированная переменная account.bank.balance не может иметь в качестве значения, значение некоторого атрибута счета acc, в данном случае значения атрибута acc.money.
Ваш алгоритм в принципе не верен.
Как я сказал выше, попробуйте составить конкретный пример с конкретным счетом и конкретным банком и пропустить этот пример через Ваш алгоритм и вы сразу поймете что Ваш алгоритм не правильный.
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
06.12.2019, 16:38
FroDK,
использовать конструкцию acc.bank.balance.
Вы не находите, что это абсурдно? Баланс ведь не у банка, а у счёта, так?
чтобы в классе Bank в атрибуте self.balance наследовались данные атрибута self.money класса Account.
Те же яйца, только в профиль. Возможно, вы не понимаете, что значит "наследоваться". Банк, по смыслу, не может наследоваться от счёта, и наоборот - тоже. Это разные вещи. Счёт может иметь ссылку на банк, это нормально. Но это не наследование.

Но в классе Bank нельзя взаимодействовать с классом Account, т.к. в нем инициализируется экземпляр класса Bank. И если так сделать, то он уходит в рекурсию.
А вот это уже интереснее. Во-первых, в банке можно сделать ссылки на все его счета. Но если ссылки ведут и туда и туда (от банка к счёту и обратно) - это циклическая ссылка, плохой стиль
Во-вторых, непонятно, что, собственно, привело к такой задаче.
В третьих, всё равно можно сделать взаимодействие между двумя классами без циклических ссылок, но это уже приёмы посложнее, поэтому для начала опишите задачу.
0
 Аватар для Semen-Semenich
5230 / 3476 / 1174
Регистрация: 21.03.2016
Сообщений: 8,304
06.12.2019, 17:07
FroDK, то есть вы хотите для каждого аккаунта узнавать его сколько денег храниться в каждом банке? ну так это же должен знать аккаунт сколько и в какой банк он положил, значить это должно храниться у пользователя. каждый банк просто хранит пользователей с их балансами.
0
2 / 1 / 1
Регистрация: 16.08.2019
Сообщений: 48
06.12.2019, 18:14  [ТС]
Имена Account и Bank я придумал для упрощения понимания. Проблему решил таким способом:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Account():
    def __init__(self):
        self.bank = Bank()
        self.money = 10
        self.bank.balance = self.money
 
class Bank:
    def __init__(self):
        self.balance = 0
 
    def get(self):
        a = self.balance * 10
        return a
 
a = Account()
print(a.bank.get())
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
06.12.2019, 18:26
FroDK, структура объектов в программе должна отражать соотношения объектов в реальном мире.
Иначе она не будет понятна никому, кроме вас, да и вам будет непонятна уже через полгода

1.
self.bank.balance =
Опять баланс у банка. Ну вот же ж...
2.
def __init__(self):
self.bank = Bank()
На каждое создание счёта вы создаёте новый банк?
0
 Аватар для Semen-Semenich
5230 / 3476 / 1174
Регистрация: 21.03.2016
Сообщений: 8,304
06.12.2019, 21:01
FroDK, вкладчик должен знать в каком банке и какой у него баланс а так же выбирать в какой банк и сколько положить на счет значить он должен хранить имена банков и знать какую кнопку нажать для получения баланса,снятия и пополнения. банк должен хранить имена (счета) пользователей а так же иметь методы пополнения, снятия, и выдачи информации по имени
0
 Аватар для Semen-Semenich
5230 / 3476 / 1174
Регистрация: 21.03.2016
Сообщений: 8,304
07.12.2019, 15:31
как вижу это я
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class Account:
    
    def __init__(self, name): 
        self.list_bank = {} # список банков пользователя
        self.name = name # ид - имя или номер счета
        
    def add_bank(self, bank_name, money ):
        
        self.list_bank[bank_name] = money
 
    def getname(self):
        return self.name
 
    def info(self):
        for key, val  in self.list_bank.items():
            print(f'bank name - {key}, balanse - {val}')
 
 
class Bank:
  
    def __init__(self, bank_name ):
        self.list_account = {} 
        self.bank_name = bank_name
 
    def getname(self):
        return self.bank_name
 
    def creation(self, acc_name, money): 
        self.list_account[acc_name] = self.list_account.get(acc_name, 0) + money
 
    def balanse(self, acc_name):
        ''' вывод баланса счета по имени вкладчика '''
        #print(f'investor - {acc_name}, deposit - {self.list_account[acc_name]}')
        ''' для примера вывод всех счетов '''
        for name, money in self.list_account.items(): # пример показа всех счетов
            print(f'investor - {name}, deposit - {money}')
 
 
def refill(bank, investor,money):
    ''' функция пополнения счета, получает банк, вкладчика и сумму.
       в банке создает запись вкладчика и сумму (или пополняет если вкладчик есть)
       у вкладчика создает запись о банке и сумме на счету '''
       
    bank.creation(investor.getname(), money)
    investor.add_bank(bank.getname(), money)
 
    
 
if  __name__ == '__main__' :
    
    bank_1 = Bank('bank1')
    bank_2 = Bank('bank2')
    ac_1 = Account('user_1')
    ac_2 = Account('user_2')
 
    print('\n-------------   user_1 --------------')
    refill(bank_1, ac_1, 500)
    refill(bank_2, ac_1, 800)
    refill(bank_2, ac_1, 800)
    refill(bank_1, ac_1, 500)
    ac_1.info()
    print('\n-------------   user_2 --------------')
    refill(bank_2, ac_2, 900)
    refill(bank_1, ac_2, 700)
    refill(bank_2, ac_2, 100)
    ac_2.info()
 
    print(' \n--------------  bank_1 info -------------')
                  
    bank_1.balanse(ac_1.getname())
    print(' \n--------------  bank_2 info -------------')
    bank_2.balanse(ac_1.getname())
профи что скажете вы?
0
1732 / 970 / 199
Регистрация: 22.02.2018
Сообщений: 2,693
Записей в блоге: 6
08.12.2019, 13:27
FroDK, Вы отказываетесь дать описание Вашей задачи. В результате люди вынуждены фантазировать, а что же Вы хотите. Если будет четко описано задание, тогда и будет четкий совет, как его решить. Вы же шифруетесь и при этом просите помощи.
Возможно Semen-Semenich, догадался, что Вы хотите. Но это остается предположением.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.12.2019, 13:27
Помогаю со студенческими работами здесь

Наследование от класса, написанного на C++
Ребят,всем привет! Такой вопрос.Есть пользовательский класс, написанный на Qt и на C++, от которого я бы очень хотел наследоваться в...

Наследование от protected класса: будут ли public члены класса Б доступны классу А
Добрый день! Если пронаследовать public класс А от protected класса Б, будут ли public члены класса Б доступны классу А, и доступны...

Наследование: Как мне определить любой из методов заданного класса внутри другого класса?
Добрый день, подскажите пожалуйста, что я делаю не так Есть файл Container.h в котором храню прототипы методов class Container ...

Объявление класса, создание экземпляров класса. Наследование классов
Вообщем начал делать программу:&quot;Создать класс Матрицы, обеспечивающего размещение матрицы произвольного размера с возможность изменения...

Наследование в класса от другого класса и интерфейса
Здравствуйте. Есть интерфейс public interface comp { void GetInfo(); } есть класс


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru