有没有办法让字典键指向原始变量?

2024-04-26 10:44:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python中遇到了类属性和字典的问题。我有以下课程:

class Test:
    def __init__(self, a):
        self.a = a
        self.dictionary = {'key': self.a}

    def check(self, string):
        print("Before: ",self.a)
        self.dictionary[string] += 2
        print("After (Dictionary): ",self.dictionary[string])
        print("After (Original variable): ",self.a)

然后我从中创建一个对象测试:

test = Test(5)

问题是:当我使用检查方法时:

test.check('key')

输出为:

Before:  5
After (Dictionary):  7
After (Original variable):  5

我所期望的是能够通过更改dictionary self.dictionary值来更改类中的属性self.a,我在dictionary self.dictionary值中指定了self.a属性。但是实际情况是,原来的属性self.a没有改变,但是字典中的值,也就是应该是self.a,已经改变了。你知道吗

有人能解释一下为什么会这样吗?我假设dict正在创建一个self.a的副本作为'key'的值。有没有办法让字典的值指向原始变量self.a,这样我就可以通过更改字典的值来更改它?你知道吗

编辑:

谢谢你们,伙计们!我现在明白了,我以为字典里会有不正确的行为。我将尝试另一种方法。你知道吗


Tags: keytestselfstringdictionary字典属性def
3条回答

这与类属性的属性无关,而是与Python中字典的工作方式以及整数是不可变的事实有关。为了说明这一点,当您这样做时也会发生同样的情况:

value = 5
dictionary = {"key": value}

dictionary["key"] += 2

print(value)
# > 5

print(dictionary["key"])
# > 7

It is important here to note that this does not work because self.a is an integer which is an immutable type in Python. This means that you will not be changing the integer's value by doing something like self.dictionary[string] += 2.

现在,对您的问题有效的方法是这样的,声明一个列表而不是一个整数,以保持可变性属性:

class Test:
    def __init__(self, a):
        self.a = [a] # instead of self.a = a
        self.dictionary = {'key': self.a}

    def check(self, string):
        print("Before: ",self.a[0])
        self.dictionary[string][0] += 2
        print("After (Dictionary): ",self.dictionary[string][0])
        print("After (Original variable): ",self.a[0])

test = Test(5)

# > Before:  5
# > After (Dictionary):  7
# > After (Original variable):  7

根据您的代码,类Test有两个实例变量: 自身a=a 自助词典={'key':self.a}

正在更改/更新的检查方法自助词典变量,而不是自身 (自助词典[字符串]+=2) 自助词典和self.a是两个不同的变量,如果要更新self.a,可以执行以下操作:

class Test:
def __init__(self, a):
    self.a = a
    self.dictionary = {'key': self.a}

def check(self, string):
    print("Before: ",self.a)
    self.a+=2
    self.dictionary[string] = self.a
    print("After (Dictionary): ",self.dictionary[string])
    print("After (Original variable): ",self.a)

输出为:

('Before: ', 5)
('After (Dictionary): ', 7)
('After (Original variable): ', 7)

self.a指向int对象,int是不可变的。也就是说他们不能改变。当你创建dictionary对象时,你说的是把这个键指向self.a指向的同一个地方。然后更改dictionary键指向的值时,因为int是不可变的,所以会在新内存位置创建一个新的into对象,因此dict键现在指向该新内存位置,而不是与self.a指向的内存位置相同。你知道吗

现在你有self.a指向内存位置保持int 5,dict键指向另一个内存位置保持int 7。你知道吗

更新

根据您的注释进行更新,使self.a和dict键值始终指向同一项的唯一方法是使用可变数据类型,例如list。因为列表是可变的,所以当您更改列表中的值时,self.a和dict仍然指向同一个列表,并且只更改了其中的值。但是,所有对int值的引用都需要通过列表中的第一个元素来访问它

class Test:
    def __init__(self, a):
        self.a = [a]
        self.dictionary = {'key': self.a}

    def check(self, string):
        print("Before: ", self.a[0])
        self.dictionary[string][0] += 2
        print("After (Dictionary): ", self.dictionary[string][0])
        print("After (Original variable): ", self.a[0])


test = Test(5)
test.check('key')

输出

Before:  5
After (Dictionary):  7
After (Original variable):  7

但正如我在评论中所说。为什么需要在类实例中对同一个值有两个不同的属性/引用。机会就是你想要达到的目标,有比这更好的方法

相关问题 更多 >