gpt4 book ai didi

python - @staticmethod 和@classmethod 如何作用于python 中的变量?

转载 作者:太空宇宙 更新时间:2023-11-03 14:46:13 25 4
gpt4 key购买 nike

我写了一个简单的程序。

class Sample:

num =45

def __init__(self):
print('Inside constructor')

@classmethod
def modifyUsingClassMethod(cls):
cls.num = cls.num + 45

@staticmethod
def modifyUsingStaticMethod():
Sample.num = Sample.num+5

s1 = Sample()
s2 = Sample()

s1.modifyUsingClassMethod()
print(s1.num, s2.num)

s1.num = s1.num + 5
print(s1.num)

s1.modifyUsingClassMethod()
print(s1.num, s2.num)

s1.modifyUsingStaticMethod()
print(s1.num, s2.num)

输出:

Inside constructor
Inside constructor
90 90
95
95 135
95 140

谁能解释一下 @staticmethod@classmethod 如何以及为什么作用于变量“num”?为什么输出显示 95,135 即使我使用 modifyUsingClassMethod() 使用 s1 实例更改了 num 的值,为什么它在两种情况下都没有使用 @staticmethod 更新@classmethod?

我想当我使用类对象引用变量 num 时,python 将变量 num 视为实例变量但是当我更改变量 num 使用类名,那么该值不会在 s1 中更新,而是在 s2 中更新。我很困惑 @classmethod@staticmethod 是如何工作的。

最佳答案

您的类方法和静态方法都只会更改类级变量。问题是您在执行此操作时隐藏了您的实例变量 s1 中的类变量 num:

s1.num = s1.num + 5

这创建了一个实例变量,它隐藏了实例命名空间中的类变量。当你访问一个对象时,将检查实例的命名空间,如果没有找到具有该名称的属性,它将尝试类命名空间,然后它将检查方法中所有类的命名空间-结果-顺序:MRO(这继承)。

考虑一下你的例子:

In [1]: class Sample:
...: num =45
...:
...: def __init__(self):
...: print('Inside constructor')
...:
...: @classmethod
...: def modifyUsingClassMethod(cls):
...: cls.num = cls.num + 45
...:
...: @staticmethod
...: def modifyUsingStaticMethod():
...: Sample.num = Sample.num+5
...:

In [2]: s1 = Sample()
...: s2 = Sample()
...:
...: s1.modifyUsingClassMethod()
...: print(s1.num,s2.num)
...:
...: s1.num = s1.num + 5
...: print(s1.num)
...:
...: s1.modifyUsingClassMethod()
...: print(s1.num,s2.num)
...:
...: s1.modifyUsingStaticMethod()
...: print(s1.num,s2.num)
...:
Inside constructor
Inside constructor
90 90
95
95 135
95 140

现在看看对象:

In [4]: vars(Sample)
Out[4]:
mappingproxy({'__dict__': <attribute '__dict__' of 'Sample' objects>,
'__doc__': None,
'__init__': <function __main__.Sample.__init__>,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'Sample' objects>,
'modifyUsingClassMethod': <classmethod at 0x107c3fe48>,
'modifyUsingStaticMethod': <staticmethod at 0x107c3ff98>,
'num': 140})

In [5]: vars(s1)
Out[5]: {'num': 95}

In [6]: vars(s2)
Out[6]: {}

你可以清楚地看到 s1 的命名空间中有 num,隐藏了 Sample 的命名空间。

注意当我们从实例 namespace 中删除 num 时会发生什么:

In [11]: del s1.num

In [12]: s1.num
Out[12]: 140

关于python - @staticmethod 和@classmethod 如何作用于python 中的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49167024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com