Я знаю, что у Python нет указателей, но есть ли способ 2
вместо этого получить этот yield
>>> 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, например, я могу сделать это:
<?php
class Form {
public $data = [];
public $fields;
function __construct($fields) {
$this->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 <iostream>
using namespace std;
int main() {
int* a;
int* b = a;
*a = 1;
cout << *a << endl << *b << endl; # 1 1
return 0;
}
a, b = b, a
.Ответы:
Это возможно, потому что она включает в себя декорированные имена и индексации - то есть совершенно разные конструкции из barenames
a
иb
что вы спрашиваете о, и с вашим запросом совершенно невозможно. Зачем просить чего-то невозможного и совершенно отличного от (возможного) того, чего вы действительно хотите ?!Может быть, вы не понимаете, насколько сильно отличаются голые и украшенные имена. Когда вы ссылаетесь на голое имя
a
, вы получаете именно тот объект, к которомуa
последний раз был привязан в этой области (или исключение, если он не был привязан в этой области) - это настолько глубокий и фундаментальный аспект Python, что он может невозможно ниспровергнуть. Когда вы ссылаетесь на декорированное имяx.y
, вы просите объект (на которыйx
ссылается объект ) предоставить «y
атрибут» - и в ответ на этот запрос объект может выполнять совершенно произвольные вычисления (и индексация очень похожа: он также позволяет производить произвольные вычисления в ответ).Ваш пример с «фактическим желанием» загадочен, потому что в каждом случае задействованы два уровня индексации или получения атрибутов, поэтому тонкость, которую вы так жаждете, может быть привнесена разными способами. Какие еще атрибуты
form.field
предполагается иметь, например, помимоvalue
? Без этих дальнейших.value
вычислений возможности будут включать:и
Наличие
.value
подсказки предлагает выбрать первую форму плюс бесполезная обертка:Если такие присваивания
form.field.value = 23
также должны устанавливать записьform.data
, тогда оболочка действительно должна стать более сложной и не такой уж бесполезной:Последний пример в Python примерно настолько близок к смыслу «указателя», насколько вам кажется, - но важно понимать, что такие тонкости могут работать только с индексированием и / или декорированными именами , никогда с голыми именами, как вы изначально просили!
источник
Вы не можете сделать это, изменив только эту строку. Ты можешь сделать:
Это создает список, присваивает ссылку a, затем также b, использует ссылку a для установки первого элемента в 2, а затем осуществляет доступ с помощью ссылочной переменной b.
источник
a
иb
список, а не значение в списке. Переменные не меняют назначения, объект - это тот же объект. Если бы он изменился, как в случае изменения целого числа (каждый из которых является разными объектами),a
теперь он будет назначен другому объекту, и нет ничего, что побуждаетb
последовать его примеру. Здесьa
не переназначается, а изменяется значение внутри объекта, которому он назначен. Посколькуb
все еще привязан к этому объекту, он будет отражать этот объект и изменения значений в нем.Это не баг, а фича :-)
Когда вы смотрите на оператор '=' в Python, не думайте о присваивании. Вы не назначаете вещи, вы их связываете. = - это оператор привязки.
Итак, в вашем коде вы даете значение 1 имя: a. Затем вы даете значение в 'a' имя: b. Затем вы привязываете значение 2 к имени 'a'. Значение, связанное с b, не изменяется в этой операции.
Исходя из C-подобных языков, это может сбивать с толку, но как только вы привыкнете к нему, вы обнаружите, что это помогает вам читать и рассуждать о своем коде более ясно: значение с именем 'b' не изменится, если вы явно измените его. И если вы сделаете «импортировать это», вы обнаружите, что дзен Python утверждает, что явное лучше, чем неявное.
Также обратите внимание, что функциональные языки, такие как Haskell, также используют эту парадигму, что имеет большое значение с точки зрения надежности.
источник
a = 1; b = a; a = 2;
точно такое же в Python, C и Java: b равно 1. Почему этот акцент делается на «= не присвоение, а привязка»?a
и вb
то время как в Python, оба они относятся к той же «1» (я думаю). Таким образом, если бы вы могли изменить значение 1 (как с объектами), оно было бы другим. Я слышал, что приводит к некоторым странным проблемам с боксом / распаковкой.Да! есть способ использовать переменную в качестве указателя в python!
С сожалением вынужден сказать, что многие ответы были частично неправильными. В принципе, каждое равное (=) присвоение разделяет адрес памяти (проверьте функцию id (obj)), но на практике это не так. Есть переменные, поведение которых равно ("=") работает в последнем термине как копия пространства памяти, в основном в простых объектах (например, объект "int"), и другие, в которых нет (например, объекты "list", "dict") ,
Вот пример присвоения указателя
Вот пример присвоения копий
Назначение указателя - довольно полезный инструмент для наложения псевдонимов без траты дополнительной памяти, в определенных ситуациях для выполнения удобного кода,
но нужно знать об этом использовании, чтобы предотвратить ошибки кода.
В заключение, по умолчанию некоторые переменные являются простыми именами (простые объекты, такие как int, float, str, ...), а некоторые являются указателями, если они назначены между ними (например, dict1 = dict2). Как их узнать? просто попробуйте этот эксперимент с ними. В IDE с переменной панелью обозревателя обычно появляется адрес памяти («@axbbbbbb ...») в определении объектов механизма указателя.
Предлагаю разобраться в теме. Есть много людей, которые наверняка знают гораздо больше по этой теме. (см. модуль "ctypes"). Надеюсь, это поможет. Наслаждайтесь хорошим использованием предметов! С уважением, Хосе Креспо
источник
Как вы можете видеть ,
a
иb
только два разных названия, ссылки на тот же неизменный объект (INT)1
. Если позже вы пишетеa = 2
, вы переназначить имяa
к другому объекту (INT)2
, но по-b
прежнему ссылается на1
:Что бы произошло, если бы вместо этого у вас был изменяемый объект, например список
[1]
?Опять же, мы ссылаемся на один и тот же объект (список)
[1]
под двумя разными именамиa
иb
. Однако теперь мы можем мутировать этот список , пока он остается тем же объектом, иa
,b
оба по- прежнему ссылается на негоисточник
С одной точки зрения, в Python все является указателем. Ваш пример очень похож на код C ++.
(Более близкий эквивалент будет использовать какой-либо тип
shared_ptr<Object>
вместоint*
.)Вы можете сделать это из- за перегрузки
__getitem__
вform.data
классе «S.источник
form.data
не класс. Нужно ли делать это единым целым, или я могу отменить это на лету? (Это просто Python dict) Кроме того, данные должны иметь обратную ссылкуform
для доступа к полям ... что делает реализацию этой уродливой.Это указатель на Python (отличается от c / c ++)
источник
Я написал следующий простой класс как, по сути, способ эмуляции указателя в python:
Вот пример использования (со страницы записной книжки jupyter):
Конечно, это также легко сделать для элементов dict или атрибутов объекта. Есть даже способ сделать то, что просил OP, с помощью globals ():
Будет напечатано 2, а затем 3.
Такой способ возиться с глобальным пространством имен - это явно ужасная идея, но она показывает, что можно (если нецелесообразно) делать то, что просил OP.
Этот пример, конечно, довольно бессмысленный. Но я обнаружил, что этот класс полезен в приложении, для которого я его разработал: математическая модель, поведение которой регулируется множеством задаваемых пользователем математических параметров различных типов (которые, поскольку они зависят от аргументов командной строки, неизвестны. во время компиляции). И как только доступ к чему-либо инкапсулирован в объект Parameter, всеми такими объектами можно управлять единообразно.
Хотя это не очень похоже на указатель C или C ++, это решает проблему, которую я бы решил с помощью указателей, если бы писал на C ++.
источник
Следующий код точно эмулирует поведение указателей в C:
Вот примеры использования:
Но теперь пора дать более профессиональный код, включая возможность удаления указателей, которые я только что нашел в своей личной библиотеке:
источник