用self调用类变量 [英] Calling class variable with self

查看:121
本文介绍了用self调用类变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎么想出这个有趣的(至少对我来说)示例.

How would you I came up with this interesting (at least to me) example.

import numpy as np


class Something(object):
    a = np.random.randint(low=0, high=10)

    def do(self):
        self.a += 1
        print(self.a)

if __name__ == '__main__':
    something = Something()
    print(something.__str__())
    something.do()
    something2 = Something()
    print(something2.__str__())
    something2.do()
    something3 = Something()
    print(something3.__str__())
    something3.do()

上面在控制台中显示以下内容:

The above prints the following in the console:

$ python test.py
<__main__.Something object at 0x7f03a80e0518>
1
<__main__.Something object at 0x7f03a80cfcc0>
1
<__main__.Something object at 0x7f03a80cfcf8>
1

我有点困惑,因为我(错误地)认为a的值会增加.

I'm a bit confused because I (wrongly) assumed the value of a would have increased.

如果使用@classmethod装饰器,我将获得预期的行为.

I'm able to obtain the behaviour I would expect if I use the @classmethod decorator.

import numpy as np


class Something(object):
    a = np.random.randint(low=0, high=10)

    @classmethod
    def do(cls):
        cls.a += 1
        print(cls.a)

if __name__ == '__main__':
    something = Something()
    print(something.__str__())
    something.do()
    something2 = Something()
    print(something2.__str__())
    something2.do()
    something3 = Something()
    print(something3.__str__())
    something3.do()

这将在控制台中正确打印以下内容.

This correctly prints the following in the console.

python test.py
<__main__.Something object at 0x7faac77becc0>
3
<__main__.Something object at 0x7faac77becf8>
4
<__main__.Something object at 0x7faac77c3978>
5

现在,在第一个示例中,我想知道当我呼叫self.a时,我正在访问什么?它不是类变量,因为我似乎无法更改其值.它也不是实例变量,因为它似乎在同一类的不同对象之间共享.你怎么称呼它?

Now, I'm wondering in the first example, when I'm calling self.a, what I'm accessing? It's not a class variable since I don't seem to be able to change its value. It's not an instance variable either, since this seems to be shared among different objects of the same class. How would you call it?

这是我使用错误的类变量吗?我知道cls名称是否是约定俗成的,所以也许我确实在访问类变量,但是由于没有用@classmethod装饰器修饰该方法,所以无法更改其值.

Is this a class variable that I'm using in the wrong way? I know the cls name if a convention, so maybe I'm truly accessing a class variable, but I'm not able to change its value because I haven't decorate the method with the @classmethod decorator.

这是对语言的一种非法使用吗?我的意思是最好的做法是为了避免在以后的阶段中引入错误,最好不要这样做?

Is this a sort of illegitimate use of the language? I mean something it's best practice to not do in order to avoid introduce a bug on a later stage?

推荐答案

正在发生的事情是self.a在不同的时间引用了两个事物.

What is happening is that self.a refers to two things at different times.

当名称不存在实例变量时,Python将在类上查找值.因此,为self.a检索的值将是类变量.

When no instance variable exists for a name, Python will lookup the value on the class. So the value retrieved for self.a will be the class variable.

但是当通过self 设置一个属性时,Python会总是设置一个实例变量.因此,现在self.a是一个新的实例变量,其值等于类变量+1.此属性遮盖了class属性,您不能再通过self来访问它,而只能通过类来访问.

But when setting an attribute via self, Python will always set an instance variable. So now self.a is a new instance variable whose value is equal to the class variable + 1. This attribute shadows the class attribute, which you can no longer access via self but only via the class.

(一个小问题,与问题无关:您永远不要直接访问双下划线方法.不要调用something2.__str__(),请调用str(something2)等)

(One minor point, which has nothing to do with the question: you should never access double-underscore methods directly. Instead of calling something2.__str__(), call str(something2) etc.)

这篇关于用self调用类变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆