@staticmethod和@classmethod如何处理python中的变量?(How does @staticmethod and @classmethod act on the variabl

编程入门 行业动态 更新时间:2024-10-06 17:22:57
@staticmethod和@classmethod如何处理python中的变量?(How does @staticmethod and @classmethod act on the variable in python?)

我写了一个简单的程序。

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工作原理。

I wrote a simple program.

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)

Output:

Inside constructor Inside constructor 90 90 95 95 135 95 140

Can anyone explain how and why the @staticmethod and @classmethod are acting on the variable 'num'?. Why does the output shows 95,135 even after I changed the value of num using s1 instance using modifyUsingClassMethod() and why not it is updating in both cases using @staticmethod and @classmethod?

I guess when I am referring to the variable num using class object then python is treating the variable num as an instance variable but when I change the variable num using Class name then the value is not updating in the s1 but in s2. I am highly confused how @classmethod and @staticmethod works.

最满意答案

class-method和static-method都只改变了类级变量。 问题在于,当您执行此操作时,您已在实例变量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的命名空间中的那个。

注意当我们从实例名称空间中删除num时会发生什么:

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

Both your class-method and your static-method only ever change the class-level variable. The issue is that you've shadowed your class-variable num inside your instance variable, s1, when you did this:

s1.num = s1.num + 5

This creates an instance variable that shadows the class variable in the instances namespace. When you access an object, the instance's namespace will be checked, if an attribute with that name isn't found, it will try the classes name-space, and then it will check the namespaces of all the classes in the method-resultion-order: the MRO (this is inheritance).

So consider your example:

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

And now look at the objects:

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]: {}

You can clearly see the namespace of s1 has num in it, shadowing the one in the namespace of Sample.

Note what happens when we delete num from the instances name-space:

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

更多推荐

本文发布于:2023-08-07 16:30:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1465256.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:变量   如何处理   staticmethod   classmethod   variable

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!