#python #python-2.7
#python #python-2.7
Вопрос:
Я пишу программу, состоящую из «главного» объекта, который отслеживает и управляет многими меньшими объектами. Вот упрощенный пример:
class My_obj:
def __init__(self, a):
self.a = a
def set_a(self, a):
self.a = a
def get_a(self):
return self.a
class Master:
def __init__(self, list_):
self.obj_list = []
for value in list_:
obj = My_obj(value)
self.obj_list.append(obj)
m = Master([0, 1, 2])
# How do I get (or set) the value of <a> from one of the My_obj instances
# within the new Master object?
Я знаю два способа сделать это. Первый — добавить метод Master
, который возвращает запрошенный объект:
def get_obj(self, index):
return self.obj_list[index]
Затем я мог бы вызвать любой метод непосредственно для объекта. Однако это кажется опасным: если последующий код удалит возвращенный объект, а затем что-то Master
попытается его найти, программа завершится сбоем.
РЕДАКТИРОВАТЬ: оказывается, это не приведет к сбою, но все равно проблема; см. Комментарии.
Второй способ — обернуть каждый метод соответствующим методом в Master
:
def set_a(self, index, a):
self.obj_list[index].set_a(a)
def get_a(self, index):
return self.obj_list[index].get_a()
Это кажется избыточным и было бы довольно утомительным в более сложном сценарии.
Кто-нибудь знает лучший способ доступа к этим методам?
Комментарии:
1. «что, если последующий код удалит возвращенный объект, а затем что-то в Master попытается его найти?» На самом деле этого не может быть. Основной объект по-прежнему будет иметь ссылку на возвращаемый объект, поэтому он не будет удален.
2. Сделайте это простым способом, и если у вас возникнут проблемы, реорганизуйте его позже.
3. Вы уже предоставили 2 способа самостоятельно. Я думаю, вам просто нужен «безопасный» способ сделать это? Почему вы считаете, что второй способ является избыточным? Это не очень подробный imo..
4. @matt, может ли последующий код каким-либо образом не изменять возвращаемый объект?
5. вы также можете установить через главный объект напрямую,
master_obj.obj_list[index].a = "some new value"
Ответ №1:
print m.obj_list[0].get_a() # prints 0
m.obj_list[0].set_a(5)
print m.obj_list[0].get_a() # prints 5
# access all the "a"'s
a_s = [o.get_a() for o in m.obj_list]
Комментарии:
1. Правильно ли обращаться к атрибутам объекта напрямую таким образом? У меня сложилось впечатление, что это должно использоваться в основном для отладки, и что реальный код должен использовать исключительно методы. Это неверно?
2. Определите «правильный»… Я предполагаю, что ответ зависит от того, что вы пытаетесь сделать, что немного сложно понять из этого примера. Если вы хотите инкапсуляцию (скрыть структуру данных, но предоставить данные), тогда вам следует создать «избыточные» методы доступа в
Master
while, если все, что вам нужно, это вложенная структура данных, вы должны сделать это без использования классов и объектов