Указатели в Python?

Я знаю, что Python не имеет указателей, но является там способом иметь этот урожай 2 вместо этого

>>> a = 1
>>> b = a # modify this line somehow so that b "points to" a
>>> a = 2
>>> b
1

?


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


В PHP, например, я могу сделать это:

fields = $fields;
        foreach($this->fields as &$field) {
            $this->data[$field['id']] = &$field['value'];
        }
    }
}

$f = new Form([
    [
        'id' => 'fname',
        'value' => 'George'
    ],
    [
        'id' => 'lname',
        'value' => 'Lucas'
    ]
]);

echo $f->data['fname'], $f->fields[0]['value']; # George George
$f->data['fname'] = 'Ralph';
echo $f->data['fname'], $f->fields[0]['value']; # Ralph Ralph

Вывод:

GeorgeGeorgeRalphRalph

ideone


Или как это в C++ (я думаю, что это правильно, но мой C++ ржав):

#include 
using namespace std;

int main() {
    int* a;
    int* b = a;
    *a = 1;
    cout << *a << endl << *b << endl; # 1 1

    return 0;
}

110
задан mpen 27 February 2019 в 21:40
поделиться

4 ответа

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

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

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

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

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

и

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

Наличие .value предлагает выбрать первую форму плюс бесполезную оболочку:

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 к смыслу «указателя», как вам кажется, - но очень важно понимать, что такие тонкости могут когда-либо работать только с индексированием и / или именами , никогда с пустыми именами, как вы изначально просили!

47
ответ дан 24 November 2019 в 03:15
поделиться

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

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

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

48
ответ дан 24 November 2019 в 03:15
поделиться

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

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

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

Пришедшим из языков, подобных C, это может показаться непонятным, но когда вы привыкнете к этому, вы обнаружите, что это помогает вам читать и рассуждать о вашем коде более ясно: значение, имеющее имя 'b', не изменится, если вы явно не измените его. А если вы сделаете "import this", то обнаружите, что "Дзен Python" утверждает, что явное лучше неявного.

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

32
ответ дан 24 November 2019 в 03:15
поделиться

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

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

(Более близким эквивалентом было бы использование какого-нибудь типа shared_ptr вместо int*.)

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

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

12
ответ дан 24 November 2019 в 03:15
поделиться
Другие вопросы по тегам:

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