Python - добавить ссылку в список [duplicate]

Позвольте мне разместить здесь решение для C ++ 03, которое я считаю максимально возможным. *

#define DECLARE_LAMBDA(NAME, RETURN_TYPE, FUNCTION) \
    struct { RETURN_TYPE operator () FUNCTION } NAME;

...

int main(){
  DECLARE_LAMBDA(demoLambda, void, (){ cout<<"I'm a lambda!"<<endl; });
  demoLambda();

  DECLARE_LAMBDA(plus, int, (int i, int j){
    return i+j;
  });
  cout << "plus(1,2)=" << plus(1,2) << endl;
  return 0;
}

(*) в мире C ++ с использованием макросов никогда не считается чистым.

85
задан Antti Haapala 26 March 2016 в 16:23
поделиться

6 ответов

Я хочу, чтобы form.data['field'] и form.field.value всегда имели одинаковое значение

Это возможно, потому что оно включает декорированные имена и индексирование, т. е. совершенно разные конструкции из названий a и b, о которых вы спрашиваете, и с вашей просьбой совершенно невозможно. Зачем спрашивать о чем-то невозможном и совершенно отличном от (возможного) предмета, который вы на самом деле хотите ?!

Возможно, вы не понимаете, насколько радикально разные имена и декорированные имена. Когда вы ссылаетесь на barename a, вы точно получаете объект a, последний связанный в этой области (или исключение, если оно не было связано в этой области) - это такой глубокий и фундаментальный аспект Python, что он не может быть искажен. Когда вы ссылаетесь на имя украшенное x.y, вы запрашиваете объект (на который ссылается объект x), чтобы указать «атрибут y» - и в ответ на это запрос, объект может выполнять полностью произвольные вычисления (и индексирование очень похоже: оно также позволяет выполнять произвольные вычисления в ответ).

Теперь ваш пример «фактического желаемого» таинственен, потому что в каждом случае два уровни индексации или получения атрибутов, поэтому тонкость, которую вы жаждете, может быть введена разными способами. Какие еще атрибуты form.field предполагается иметь, например, помимо value? Без дополнительных .value вычислений возможности включали бы:

class Form(object):
   ...
   def __getattr__(self, name):
       return self.data[name]

и

class Form(object):
   ...
   @property
   def data(self):
       return self.__dict__

. Наличие .value предполагает выбор первой формы, а также вид -useless wrapper:

class KouWrap(object):
   def __init__(self, value):
       self.value = value

class Form(object):
   ...
   def __getattr__(self, name):
       return KouWrap(self.data[name])

Если присваивания такие form.field.value = 23 также должны установить запись в form.data, тогда обертка должна стать более сложной, а не все это бесполезно:

class MciWrap(object):
   def __init__(self, data, k):
       self._data = data
       self._k = k
   @property
   def value(self):
       return self._data[self._k]
   @value.setter
   def value(self, v)
       self._data[self._k] = v

class Form(object):
   ...
   def __getattr__(self, name):
       return MciWrap(self.data, name)

Последний пример примерно такой же близкий, как и в Python, к понятию «указатель», как вам кажется, - но важно понять, что такое тонкости могут работать только с индексированием и / или декорированными именами , никогда с именами баров, как вы изначально задавали!

35
ответ дан Alex Martelli 1 September 2018 в 03:02
поделиться

Да! есть способ использовать переменную как указатель в python!

Мне жаль, что многие ответы были частично неправильными. В принципе, каждая равная (=) передача разделяет адрес памяти (проверьте функцию id (obj)), но на практике это не так. Существуют переменные, поведение которых равно ("=") работает в последнем члене как копия пространства памяти, главным образом в простых объектах (например, объект "int") и другие, в которых нет (например, объекты "list", "dict"), .

Ниже приведен пример назначения указателя

dict1 = {'first':'hello', 'second':'world'}
dict2 = dict1 # pointer assignation mechanism
dict2['first'] = 'bye'
dict1
>>> {'first':'bye', 'second':'world'}

. Ниже приведен пример назначения копирования

a = 1
b = a # copy of memory mechanism. up to here id(a) == id(b)
b = 2 # new address generation. therefore without pointer behaviour
a
>>> 1

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

class cls_X():
   ...
   def method_1():
      pd1 = self.obj_clsY.dict_vars_for_clsX['meth1'] # pointer dict 1: aliasing
      pd1['var4'] = self.method2(pd1['var1'], pd1['var2'], pd1['var3'])
   #enddef method_1
   ...
#endclass cls_X

, но об этом следует помнить, чтобы предотвратить ошибки кода.

To заключить, по умолчанию некоторые переменные являются именами (простые объекты, такие как int, float, str, ...), а некоторые - указатели при назначении между ними (например, dict1 = dict2). Как их распознать? просто попробуйте этот эксперимент с ними. В IDE с панелью переменных explorer обычно отображается адрес памяти («@axbbbbbb ...») в определении объектов-указателя-механизма.

Я предлагаю исследовать в этой теме. Есть много людей, которые знают гораздо больше об этой теме. (см. модуль «ctypes»). Надеюсь, это полезно. Наслаждайтесь хорошим использованием объектов! С уважением, Хосе Креспо

16
ответ дан 4 revs 1 September 2018 в 03:02
поделиться
id(1)
1923344848  # identity of the location in my memory    
>> a = 1
>> b = a  # or equivalently b = 1, because 1 is immutable
>> id(a)
1923344848
>> id(b)
1923344848

Как вы видите a и b, это просто имена, ссылающиеся на один и тот же объект 1. Если позже вы напишете a = 2, вы переназначите имя a на другой объект 2, но не на b, который будет продолжать ссылаться на 1:

>> id(2)
1923344880
>> a = 2
>> id(a)
1923344880  # same as id(2)
>> id(b)
1923344848  # same as id(1)

Что будет произойдет, если у вас есть изменяемый объект?

>> id([1])
328817608
>> id([1])
328664968  # different
>> a = [1]
>> id(a)
328817800
>> id(a)
328817800  # same as before
>> b = a  # not equivalent to b = [1]
>> id(b)
328817800  # same as id(a)

Теперь вы ссылаетесь на один и тот же объект списка по именам a и b. Вы можете мутировать этот список, но он останется одним и тем же объектом, а a и b будут продолжать ссылаться на него

>> a[0] = 2
>> a
[2]
>> b
[2]
>> id(a)
328817800  # same as before
>> id(b)
328817800  # same as before
2
ответ дан Andyk 1 September 2018 в 03:02
поделиться

С одной точки зрения, все является указателем на Python. Ваш пример очень похож на C ++-код.

int* a = new int(1);
int* b = a;
a = new int(2);
cout << *b << endl;   // prints 1

(Более близкий эквивалент использовал бы некоторый тип shared_ptr<Object> вместо int*.)

пример: я хочу, чтобы form.data ['field'] и form.field.value всегда имели одинаковое значение. Это не совсем необходимо, но я думаю, что было бы хорошо.

Вы можете сделать это, перегрузив __getitem__ в классе form.data.

11
ответ дан dan04 1 September 2018 в 03:02
поделиться

Это не ошибка, это особенность: -)

Когда вы смотрите на оператор '=' в Python, не думайте в терминах назначения. Вы не назначаете вещи, вы их связываете. = является оператором связывания.

Итак, в вашем коде вы указываете значение 1 a name: a. Затем вы указываете значение в 'a': b. Затем вы привязываете значение 2 к имени «a». Значение, связанное с b, не изменяется в этой операции.

Исходя из C-подобных языков, это может сбивать с толку, но как только вы привыкнете к нему, вы обнаружите, что он помогает вам читать и рассуждать о вашем коде более четко: значение, которое имеет имя «b», не изменится, если вы явно не измените его. И если вы выполните «импорт этого», вы обнаружите, что Zen of Python утверждает, что Explicit лучше, чем неявный.

Обратите также внимание на то, что функциональные языки, такие как Haskell, также используют эту парадигму, значение с точки зрения надежности.

32
ответ дан David Harks 1 September 2018 в 03:02
поделиться

Вы не можете сделать это, изменяя только эту строку. Вы можете сделать:

a = [1]
b = a
a[0] = 2
b[0]

Создает список, назначает ссылку на a, а затем b также использует ссылку для установки первого элемента в 2, затем обращается к нему с использованием ссылочной переменной b.

35
ответ дан Matthew Flaschen 1 September 2018 в 03:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: