0
0 Комментариев

Здравствуйте, постараюсь максимально подробно описать суть проблемы:

Почти год программирую на Python 3, потребовалось использовать указатель на переменную, которая может являться как изменяемой (mutable), например list, так и неизменяемой (immutable), например float.

Требуется используя адрес переменной «A» записать адрес в переменную «B», таким образом, чтобы после изменения «A», через переменную «B» можно было узнать значение в «A».

Пример на С/C++:

int A=0;
int *B;
B=&A;
printf("%d\n", *B); //ответ: 0
A=1;
printf("%d\n", *B); //ответ: 1

Пытаюсь реализовать на Python и написать функцию, которая принимает два элемента, например «element» и «under_element», где «element» типа список (list), «under_element» любой объект (float, str, list, «мой_объект»).

Функция записывает адрес объекта «under_element», в один из элементов списка «element» так, что при изменении «under_element» используя объект «element» можно было бы узнать актуальное значение «under_element»

Пример структуры функции на Python 3 («укороченный»):

def f(element, under_element, i=0):
    print("depth=", i, "\tfs_element=", element)
    if(i<1):
        f(element[0], under_element, i+1)
    else:
        element=under_element
    print("depth=", i, "\tff_element=", element)
 
element=[[0],[1]]
under_element='str'
print("start_element=", element, "\n")
 
f(element, under_element)
 
under_element='list'
print("\nfinish_element=", element)

Результат работы программы:

start_element= [[0], [1]]
 
depth= 0    fs_element= [[0], [1]]
depth= 1    fs_element= [0]
depth= 1    ff_element= str
depth= 0    ff_element= [[0], [1]]
 
finish_element= [[0], [1]]

Желаемый результат работы программы:

start_element= [[0], [1]]
 
depth= 0    fs_element= [[0], [1]]
depth= 1    fs_element= [0]
depth= 1    ff_element= str
depth= 0    ff_element= ['str', [1]]
 
finish_element= ['list', [1]]

Нашел решение состоящее из четырех пунктов:

  1. все элементы заключать в list, пример: under_element=['str']
  2. передавать в функцию переменные в виде лист
  3. обращаться к записываемому объекту без дополнительных [] (без указания глубины)
  4. обращаться к объекту, в который записываем с дополнительным [] (с указанием глубины)

Пример переделанной функции:

def f(element, under_element, i=0):
    print("depth=", i, "\tfs_element=", element)
    if(i<1):
        f(element[0], under_element, i+1)
    else:
        element[0]=under_element
    print("depth=", i, "\tff_element=", element)
 
element=[[0],[1]]
under_element=['str']
print("start_element=", element, "\n")
 
f(element, under_element)
 
under_element[0]='list'
print("\nfinish_element=", element)

Результат работы программы:

start_element= [[0], [1]]
 
depth= 0    fs_element= [[0], [1]]
depth= 1    fs_element= [0]
depth= 1    ff_element= [['str']]
depth= 0    ff_element= [[['str']], [1]]
 
finish_element= [[['list']], [1]]

Недостатки данного решения:

  1. мусор в массивах и коде программы
  2. нет гарантии, что пользователь функции пользуется переменными, как указано выше к данному примеру, и не передаст объект являющийся immutable (float, str и др.)

Повторюсь:

Требуется обратиться к объекту (1) через другой объект (2), например через элемент списка, или чтобы значение объекта (1) было в объект (2), даже после изменения объекта (1), другими словами всегда соответствовало значению объекта(1)

Пример:

A=0

запоминаем адрес в «B»

А=1

смотрим на «А» через «B» получаем 1

(после записи адреса «A» в «B», нельзя обратиться к «A», но требуется взять значение «А», которое в нее записано)


Добавить комментарий