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

Как задать имя объекту класса из списка?

16.06.2021, 15:03. Показов 3142. Ответов 4

Студворк — интернет-сервис помощи студентам
Написал класс Article и создал список some_list, где заполнил его строками article и порядковыми номерами:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Article:
    def __init__(self,id, title):
        self.id = id
        self.title = title
        
some_list = []
for i in range(1,5):
    current_name_list = "article{}".format(i)
    some_list.append(current_name_list)
print(some_list)
 
for i in range(1,5):
    some_list[i-1] = Article(id = i, title = "title{}".format(i))
    print("id = {0} title = {1}".format(some_list[i-1].id, some_list[i-1].title))
print(article1.id)
Далее с помощью того же списка some_list создаю объекты классов, однако он вместо того, чтобы сделать значение article1 объектом класса Article, объектами класса становятся, видимо, сами элементы списка:
Code
1
2
3
4
5
6
7
8
9
['article1', 'article2', 'article3', 'article4']
id = 1 title = title1
id = 2 title = title2
id = 3 title = title3
id = 4 title = title4
[<__main__.Article object at 0x7f66939f8ca0>, <__main__.Article object at 0x7f6693a527c0>, <__main__.Article object at 0x7f66939950d0>, <__main__.Article object at 0x7f6693995130>]
Traceback (most recent call last):
  File "<string>", line 16, in <module>
NameError: name 'Article1' is not defined
Мне бы хотелось, чтобы значения (article1, article2, и т. д.) списка some_list сами стали объектами класса. Как это можно сделать, или это невозможно?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.06.2021, 15:03
Ответы с готовыми решениями:

Qt. Как задать точное расположение на графической сцене объекту класса, наследованного от QWidget
Как задать точное расположение на графической сцене объекту класса, наследованного от QWidget. Дело в том, что для QGrpahicsItem есть метод...

Как каждому объекту класса из списка назначить свою процедуру?
как каждому объекту класса в списке назначить свою процедуру при заполнении списка объектами, со свойствами я разобрался, а вот с методами...

Задать имя и значение объекту, который достали из библиотеки
Здравствуйте. Щас делаю различные мат. модели, в данный момент обратная матрица. Объекты из библиотеки таскаю с помощью addChild. Для...

4
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
16.06.2021, 15:30
SalavatGood, вот это у вас каша в голове, вот это я понимаю "начинать обучать школьников сразу с питона".

Вот это самое близкое к оригиналу, из того "как я вижу", диплом телепата ещё не получил.
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Article:
    def __init__(self, id, title):
        self.id = id
        self.title = title
 
 
some_list = []
for i in range(1, 5):
    some_list.append(Article(id=i, title="article{}".format(i)))
    print("id = {0} title = {1}".format(some_list[i-1].id, some_list[i-1].title))
FIND = 2
print(some_list[FIND-1].id)
Но, лучше словарём
1
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
16.06.2021, 15:37
SalavatGood, просто забыл написать. __repr__ для своего класса.

Добавлено через 3 минуты
Python
1
2
3
4
5
6
7
8
9
10
11
class Article:
    def __init__(self, id, title):
        self.id = id
        self.title = title
 
    def __repr__(self):
        return f'Article(id={self.id}, title={self.title})'
 
 
some_list = [Article(i, f'title{i}') for i in range(1, 5)]
print(some_list)
1
1732 / 970 / 199
Регистрация: 22.02.2018
Сообщений: 2,693
Записей в блоге: 6
17.06.2021, 14:05
Цитата Сообщение от SalavatGood Посмотреть сообщение
Мне бы хотелось, чтобы значения (article1, article2, и т. д.) списка some_list сами стали объектами класса.
Это сделать можно, с помощью функции exec(). Но это имеет смысл только в том случае, если в дальнейшем в коде будут использоваться эти имена экземпляров класса.
То есть код ниже должен знать, что такие имена переменных могут быть и использовать их для работы с ними.
Есть еще способ, с помощью метакласса type, но это отдельная тема.
1
1732 / 970 / 199
Регистрация: 22.02.2018
Сообщений: 2,693
Записей в блоге: 6
18.06.2021, 09:31
SalavatGood, У Вас подход не верный, и поэтому алгоритм неверный.
Судя по всему, когда вводится (article1, article2, и т. д.), нельзя исключать, что номера артиклей будут повторяться. И если будут создаваться экземпляры класса с этими именами, то появятся переменные с одинаковыми именами, что будет приводить к ошибкам.
Правильнее каждому экземпляру класса давать уникальное имя.
Но так как , если не известно сколько экземпляров класса может быть создано, то имеет смысл использовать другой метод.
Создаваемым экземплярам класса не присваивать имена, а что бы работать с ними помещать их в словарь. Где объект экземпляра класса будет значением, а ключом будет значение его атрибута.
Так как ключ должен быть уникальным, то и значения атрибута экземпляра класса (используемое для ключа словаря) должно быть уникальным. Например атрибут экземпляра класса называемый ключом и устанавливаемый автоматически при создании экземпляра класса.
Для примера могу показать шаблон журнала записей, в котором используется данный прием.
Я сначала создал шаблон из 5-ти модулей, мне с ним удобнее работать. Но его не удобно выкладывать сюда на форум. Теперь я его загнал в один файл.
Если Вы опишите, какие поля должны быть у Вашей записи в журнале, кроме артикула, я по своему шаблону (убрав комментарии нужные только шаблону) напишу Вам работающий журнал для ведения в нем записей.
Кстати, в этот шаблон легко добавлять различную обработку записей.
Вот сам шаблон
Кликните здесь для просмотра всего текста
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
"""
Журнал записей.
Программа для ведения записей.
"""
# <Вид записей>
 
# (КОММЕНТАРИИ БОЛЬШИМИ БУКВАМИ В СКОБКАХ) являются альтернативным представлением реальных действий,
#                                          которые описываются в алгоритме решения задачи
 
# (ПС) - обозначение кода, относящегося к вспомогательным программным средствам
 
# (М)  - обозначение кода,
#        относящегося непосредственно к созданию программной модели реального мышления
 
# p<Имя> - экземпляр программы              (экземпляр из класса программы в сценарии,
#                                            если класс программы существует в сценарии (в основном блоке))
# t<Имя> - экземпляр инструментария         (экземпляр из класса блока program_Tools) 
#                                           (СЕАНС РАБОТЫ ПРОГРАММЫ)-(ОДИН ИЗ СЕАНСОВ)
# d<Имя> - экземпляр базы данных (БД)       (из класса блока input_Data)
#                                           (ОДНА ИЗ БАЗ ДАННЫХ)
# m<Имя> - модуль                           сокращенное имя блока,
#               одновременно атрибут экземпляра t, для доступа к блоку (например t1.mID,
#                                                            доступ к блоку input_Data),
# (С ПОМОЩЬЮ КОММУТАТОРА ОБЕСПЕЧИВАЕТСЯ ДОСТУП ИЗ ЛЮБОГО МОДУЛЯ К ЛЮБОМУ ДРУГОМУ МОДУЛЮ ДАННОГО ПРОЕКТА)
#                                           
# <Имя класса><номер экземпляра> - экземпляр класса  (ОБЪЕКТ КЛАССА)
 
# t1 - экземпляр класса Prog_Tools (СЕАНС t1 РАБОТЫ ПРОГРАММЫ)
# j1 - экземпляр класса Journal (ЖУРНАЛ j1) 
# iD_1 - экземпляр класса входных данных Input_Data, загружается в "журнал" j1
#        (БАЗА ДАННЫХ ВО ВХОДНЫХ ДАННЫХ, В КОТОРУЮ ЗАГРУЖАЕТСЯ ВНЕШНЯЯ БАЗА ДАННЫХ)
# oD_1 - экземпляр класса выходных данных Output_Data, загружается из "журнала" j1
 
 
 
 
# *************** Блок "ПРОГРАМНЫЕ СРЕДСТВА" program_Tools ********************************
"""
Блок program_Tools.
Содержит программные инструменты
(например такие,
  загрузка данных с внешнего носителя и сохранение данных на внешнем носителе, в общем все,
  что относится чисто к работе вспомогательных программ, а не к формируемой модели)
#В том числе выполняет роль коммутатора, связывающего все модули конкретного проекта.
#Под каждый проект пишется свой уникальный код коммутатора,
#          который жестко связан со всеми модулями проекта.
#Код коммутатора пишется по шаблону. 
#В каждом модуле проекта создается переменная, через которую коммутатор 
#          подключает модуль к себе.
#(С ПОМОЩЬЮ КОММУТАТОРА ЛЮБОЙ МОДУЛЬ ПРОЕКТА
#                              ИМЕЕТ ДОСТУП К ЛЮБОМУ ДРУГОМУ МОДУЛЮ ЭТОГО ПРОЕКТА)
"""
 
# p<Имя> - экземпляр программы              (из класса сценария, если он существует, основного модуля)
# t<Имя> - экземпляр инструментария         (из класса модуля program_Tools)
# iD<Имя> - экземпляр базы данных (БД)       (из класса Input_Data модуля input_Data)
# oD<Имя> - экземпляр базы данных (БД)       (из класса Output_Data модуля output_Data)
# m<Имя> - модуль
# <Имя класса><номер экземпляра> - экземпляр класса
 
# iD_1 - база данных "Журнал записей", для загрузки в "журнал" j1
 
import shelve
 
class Prog_Tools:
    def __init__(self):
        self.iD_1 = Input_Data()  # создание экземпляра iD_1 класса базы данных Input_Data
        self.oD_1 = Output_Data() # создание экземпляра oD_1 класса базы данных Output_Data
                                     # при необходимости можно создать дополнительные экземпляры базы данных
 
        self.j1 = Journal()           # создание экземпляра класса
                                      # для работы с классом Journal блока journal
                                      # имя журнала используется то же, что и в iD_1.dbName
                                      # первоначально словарь записей копируется из iD_1.dic_recs,
                                      # который загружается из внешней БД
        self.j1.dbName = self.iD_1.dbName     # название журнала
        self.j1.dic_recs = dict(self.iD_1.dic_recs.items())    # словарь записей, который загружается из БД
                                          # и с которым программма динамически работеет,
                                          # чтобы затем измененные данные сохранить в БД
    def load_DB(self):
        # загрузка записей из базы данных db1, при необходимости добавить дополнительные БД
        db1 = shelve.open(self.iD_1.dbName)     # открытие базы данных "Журнал записей" (имя берется
                                              # из атрибута dbName экземпляра класса Input_Data)
        self.iD_1.dic_recs = dict(db1.items())  # загрузка записей из базы данных в атрибут dic_recs
                                              # экземпляра класса Input_Data (в словарь экземпляра класса)
        db1.close()                           # закрытие базы данных
        self.oD_1.dic_recs = dict(self.iD_1.dic_recs.items())  # копирование базы данных
                                                               # в выходные данные 
 
    def save_DB(self):
 
        # сохранение записей в базе данных db1, при необходимости добавить дополнительные БД
        db1 = shelve.open(self.oD_1.dbName)     # открытие базы данных
        for (key, record) in self.oD_1.dic_recs.items():  # запись содержимого из словаря dic_recs
            db1[key] = record                            # экземпляра oD_1 класса Output_Data
                                                         # во внешнюю базу данных
        db1.close()                           # закрытие базы данных
 
    def print_j1(self):
        # вывод текущего состояния журнала j1
        print(self.j1.dbName.upper())                             # вывод названия журнала
        print('*' * 49)
 
        lst_j = sorted(self.j1.dic_recs.values(), key=lambda item: item.field1) # сортировка записей
                                                                                # по фамилиям
        print(f"{'KEY |':^4}{'   Поле1    |':^15}{'    Поле2     |':^13}{'   Поле3     |':^17}")  # шапка таблицы
        print('_' * 49)
        for rec in lst_j:                    # вывод записей
            print(f"{(rec.keyRec+'.'):4}{rec.field1:15}{rec.field2:13}{rec.field3:17}")
 
        print('*' * 49)
 
# ******************* КОНЕЦ БЛОКА Програмные средства program_Tools ************************
 
 
 
# ********************* Блок "ВХОДНЫЕ ДАННЫЕ" input_Data ***********************************
 
"""
Оформление модуля в виде класса позволяет создавать сразу несколько баз данных 
и работать с ними одновременно.
Используется для хранения данных.
"""
 
class Input_Data:
    def __init__(self, dic_recs={}):
        self.dbName = "Входные данные"
        self.dic_recs = dic_recs         # словарь записей
 
# *********************** КОНЕЦ БЛОКА Входные данные input_Data ****************************
 
 
 
# ************************ Блок "ВЫХОДНЫЕ ДАННЫЕ" output_Data ******************************
 
"""
Оформление модуля в виде класса позволяет создавать сразу несколько баз данных 
и работать с ними одновременно.
Используется для хранения данных.
"""
 
class Output_Data:
    def __init__(self, dic_recs={}):
        self.dbName = "Выходные данные"
        self.dic_recs = dic_recs      # словарь записей
 
# *********************** КОНЕЦ БЛОКА Выходные данные output_Data *************************
 
 
 
# ***************************** Блок "ЖУРНАЛ" journal *************************************
 
class Journal:
    def __init__(self, currentKey=None):
        self.dbName = None        # название журнала
        self.currentKey = currentKey      # номер текущей записи в журнале
        self.dic_recs = None    # словарь записей, который загружается из БД
                                          # и с которым программма динамически работеет,
                                          # чтобы затем измененные данные сохранить в БД
    def add_rec(self):
        # добавление в журнал записи
        field1 = input('Поле1: ')    # (М) вводятся значения полей записи
        field2 = input('Поле2: ')
        field3 = input('Поле3: ')
        field4 = input('Поле4: ')
        field5 = input('Поле5: ')
        field6 = input('Поле6: ')
        if len(t1.j1.dic_recs)>0:                                      # если список не пуст,
            L = sorted(t1.j1.dic_recs.items(), key=lambda item: int(item[0])) # то к максимальному значению
            keyRec = str(int(L[-1][0]) + 1)                # ключа записи прибавляется единица
        else:                                     # иначе записи присваивается ключ равный 1
            keyRec = "1"
        record = Record(keyRec, field1, field2, field3, field4, field5, field6) # создается запись, экземпляр класса Record
        self.dic_recs[keyRec] = record     #  записывается в словарь self.dic_recs
        t1.oD_1.dic_recs[keyRec] = record # записывается в словарь выходных данных
        db1 = shelve.open(t1.oD_1.dbName)       # открытие базы данных
        db1[keyRec] = record                    # запись во внешнюю базу данных
        db1.close()                             # закрытие базы данных
 
    def del_rec(self, key):
        # удаление записи из журнала
        del self.dic_recs[key]                  # удаление из журнала
        del t1.oD_1.dic_recs[key]               # удаление из выходных данных
        db1 = shelve.open(t1.oD_1.dbName)       # открытие базы данных
        del db1[key]                            # удаление записи из внешней базы данных
        db1.close()                             # закрытие базы данных
 
class Record:
    # класс Запись
    def __init__(self, keyRec, field1, field2, field3, field4, field5, field6):
        # инициализация атрибутов экземпляров класса
        self.keyRec = keyRec                   # ключ записи
        self.field1 = field1                   # Поле1
        self.field2 = field2                   # Поле2
        self.field3 = field3                   # Поле3
        self.field4 = field4                   # Поле4
        self.field5 = field5                   # Поле5
        self.field6 = field6                   # Поле6
 
# ************************** КОНЕЦ БЛОКА Журнал journal **********************************
 
 
 
if __name__ == '__main__':
 
    t1 = Prog_Tools()              # (ПС) Создание экземпляра t1 класса Prog_Tools 
                                       # (СОЗДАНИЕ ЭКЗЕМПЛЯРА ВСПОМОГАТЕЛЬНЫХ ПРОГРАММ,
                                       # АКТИВАЦИЯ ВСПОМОГАТЕЛЬНЫХ ПРОГРАММ)
    t1.iD_1.dbName = "Журнал записей"     # (М) Присвоение имени базе данных (журналу) во входных данных
    t1.oD_1.dbName = "Журнал записей"     # (М) Присвоение имени базе данных в выходных данных
    t1.load_DB()                       # (ПС) загрузка записей из внешней БД в словарь dic_recs входных данных
                                       # (ЗАГРУЗКА ВНЕШНЕЙ БД ВО ВХОДНЫЕ ДАННЫЕ)
    
    # здесь вставляется код работы со словарем dic_recs, после создания содержащего его журнала
    j = t1.j1                     # (М) экземпляр j для работы с классом Journal модуля journal
    j.dbName = t1.iD_1.dbName          # (М) имя журнала используется то же, что и в dj.dbName
                                  # первоначально словарь записей копируется из iD_1.dic_recs,
                                  # который загружается из внешней БД
    j.dic_recs = dict(t1.iD_1.dic_recs)     # (ПС) копирование базы данных из входных данных в журнал
 
# (ПС) (ВЫВОДИМ МЕНЮ)
    while True:
        lst_1 = ["1 - Вывести список", "2 - Добавить запись", "3 - Удалить запись", "Для выхода нажмите Enter"]  # меню
        print(*lst_1, sep='\n')
        print()
        m = input('Введите число для выбора действия: ')           # (М) позиция меню
        print()
        if m == "1":
            t1.print_j1()          # (М) (ИЗ ЖУРНАЛА ВЫВЕСТИ СПИСОК)
            print()
        elif m == "2":
            t1.j1.add_rec()          # (М) (ДОБАВИТЬ ЗАПИСЬ)
            print()
        elif m == "3":
            key = input('Введите номер ключа KEY удаляемой записи: ')
            t1.j1.del_rec(key)                     # (М) УДАЛИТЬ ЗАПИСЬ
            print()
        elif m == '':
            t1.oD_1.dic_recs = dict(j.dic_recs)     # (ПС) копирование базы данных из журнала в выходных данные
            break                    # (М) (ВЫХОД ИЗ МЕНЮ)
 
    t1.save_DB()             # сохранение записей из словаря dic_recs во внешнюю БД
                             # (СОХРАНЕНИЕ ВЫХОДНЫХ ДАННЫХ ВО ВНЕШНЕЙ БАЗЕ ДАННЫХ)


Добавлено через 9 минут
В блоке "Журнал" в методе add_rec используется та методика, о которой я написал выше. Что не понятно, спрашивайте.

Добавлено через 2 минуты
Сорри, в комментариях я не все вычистил, из того , что относится к много модульному шаблону. Например упоминание о Коммутаторе, который нужен только в том шаблоне, для связывание модулей в одно целое.

Добавлено через 2 минуты
Данный код можете проверить, он рабочий.
В поля можете заносить свою информацию. Если дадите, какие нужны Вам поля, я заменю названия полей и уберу не нужные Вам комментарии.
Количество полей можно сделать любым.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.06.2021, 09:31
Помогаю со студенческими работами здесь

Дать имя объекту, функции или переменной из списка, которое выбирается рандомом
Доброго времени суток. С Python столкнулся недавно, поэтому не судите строго. Есть следующая задача. (Сначала приведу скрипт (скрипт не...

Возможно ли как-то, зная имя класса, вернуть в каком-либо методе имя класса?
Добрый день! Интересуюсь. Есть Обобщенный метод, например: Add&lt;T&gt;(string nameElement). Какой конкретно Т определяется...

Как обратиться к объекту класса родителя, из объекта дочерного класса
Вопрос скорее про c++ в целом, чем конкретно про qt имеется классы namespace Ui { class Widget; } class Widget : public...

Как обратиться к объекту S класса Data из класса Date?
# include &lt;iostream&gt; # include &lt;vector&gt; using namespace std; class Date; class Data { private: unsigned int year; unsigned...

Как задать импульс 3D объекту?
Всем привет! Как задать импульс 3D объекту?


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru