Я знаю, что 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
Или как это в C++ (я думаю, что это правильно, но мой C++ ржав):
#include
using namespace std;
int main() {
int* a;
int* b = a;
*a = 1;
cout << *a << endl << *b << endl; # 1 1
return 0;
}
Я хочу
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 к смыслу «указателя», как вам кажется, - но очень важно понимать, что такие тонкости могут когда-либо работать только с индексированием и / или именами , никогда с пустыми именами, как вы изначально просили!
Вы не можете сделать это, изменив только эту строку. Вы можете сделать:
a = [1]
b = a
a[0] = 2
b[0]
Это создает список, присваивает ссылку a, затем также b, использует ссылку a для установки первого элемента на 2, затем осуществляет доступ с помощью ссылочной переменной b.
Это не ошибка, это особенность :-)
Когда вы смотрите на оператор '=' в Python, не думайте в терминах присваивания. Вы не присваиваете вещи, вы их связываете. = - это оператор связывания.
Итак, в вашем коде вы присваиваете значению 1 имя: a. Затем вы присваиваете значению в 'a' имя: b. Затем вы связываете значение 2 с именем 'a'. Значение, привязанное к b, при этой операции не меняется.
Пришедшим из языков, подобных C, это может показаться непонятным, но когда вы привыкнете к этому, вы обнаружите, что это помогает вам читать и рассуждать о вашем коде более ясно: значение, имеющее имя 'b', не изменится, если вы явно не измените его. А если вы сделаете "import this", то обнаружите, что "Дзен Python" утверждает, что явное лучше неявного.
Заметим также, что функциональные языки, такие как Haskell, также используют эту парадигму, что очень полезно с точки зрения надежности.
С одной точки зрения, все в 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
.