Python中的指针?

2024-05-12 20:59:32 发布

您现在位置: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中,我可以这样做:

<?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

ideone


<>或者类似于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;
}

Tags: echoformidfieldfieldsdatavaluepublic
3条回答

你不可能只改变这一行。你可以:

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

它创建一个列表,将引用分配给a,然后b也使用a引用将第一个元素设置为2,然后使用b引用变量进行访问。

I want form.data['field'] and form.field.value to always have the same value

这是可行的,因为它涉及修饰名称和索引——即,完全不同于您所要求的裸名称ab的不同构造,并且您的请求是完全不可能的。为什么要问一些不可能的事情,与你真正想要的(可能的)事情完全不同?!

也许你不知道光名和修饰名有多么不同。当你引用一个裸名a时,你得到的正是这个作用域中最后绑定到的对象a(如果它没有绑定在这个作用域中,则是一个异常)——这是Python的一个非常深入和基本的方面,它不可能被颠覆。当您引用修饰的名称x.y时,您要求一个对象(对象x引用)提供“the y属性”--并且响应该请求,该对象可以执行完全任意的计算(索引非常相似:它还允许响应执行任意计算)。

现在,您的“实际desiderata”示例很神秘,因为在每种情况下都涉及两个级别的索引或属性获取,所以您渴望的微妙之处可以通过多种方式引入。例如,除了value之外,form.field还有哪些其他属性?如果没有进一步的计算,可能包括:

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中,后一个示例与您所希望的“指针”的含义几乎一样接近——但必须理解,这种微妙之处只能与索引和/或修饰名称一起使用,而不能像您最初要求的那样使用裸名称!

这不是一个bug,而是一个特性:-)

当您在Python中查看“=”运算符时,不要考虑赋值。你不分配东西,你就把它们绑起来。=是绑定运算符。

因此,在代码中,您将值1命名为:a。然后,您将值“a”命名为:b。然后,您将值2绑定到名称“a”。绑定到b的值在此操作中不会更改。

来自于类似于C的语言,这可能会让人困惑,但是一旦你习惯了它,你就会发现它有助于你更清楚地阅读和推理你的代码:名为“b”的值不会改变,除非你显式地改变它。如果你做一个“import this”,你会发现Python的Zen声明显式优于隐式。

还要注意,像Haskell这样的函数式语言也使用这种范式,在健壮性方面具有很大的价值。

相关问题 更多 >