Python class 属性及其初始化

Python class attributes and their initialization

我是 python 的新手,这些天我正在探索 classes。我有一个关于 classes 中的属性和变量的问题:在 class 的主体中仅通过 q=1 定义属性与通过在内部定义 self.q=1 之间有什么区别__init__?例如,下面两种可能性有什么区别?

class MyClass1:
    q=1
    def __init__(self,p):
        self.p=p
    def AddSomething(self,x):
        self.q = self.q+x

class MyClass2:
    def __init__(self,p):
        self.q=1
        self.p=p
    def AddSomething(self,x):
        self.q = self.q+x

例如输出:

>>> my=MyClass1(2)
>>> my.p
2
>>> my.q
1
>>> my.AddSomething(7)
>>> my.q
8

不依赖于使用的是MyClass1还是MyClass2。在 MyClass1MyClass2 中都没有发生错误。

此 classes 中的 q 属性之间最显着的区别在于,在 MyClass1 实现中,变量将在此 class 的所有实例之间共享,而在 MyClass2 中,它仅在该特定对象的范围内可见。

一些文档:https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables

class 中的

q=1 是一个 class 属性,与整个 class 关联,而不是 class 的任何特定实例。使用 class 本身可以最清楚地访问它:MyClass1.q.

实例属性直接分配给class的实例,通常在__init__中通过分配给self(例如self.p = p),但是你可以随时为实例分配属性。

Class 属性可以 read 使用 class 绑定 (MyClass.q) 或实例绑定 (my.q ,假设它没有被具有相同名称的实例属性隐藏)。它们只能是 set,但是,使用 class 绑定。使用实例绑定设置值 always 修改实例属性,必要时创建它。考虑这个例子:

>>> a = MyClass1()
>>> a.q
1
>>> a.q = 3    # Create an instance attribute that shadows the class attribute
3
>>> MyClass1.q
1
>>> b = MyClass1()
>>> b.q   # b doesn't have an instance attribute q, so access the class's
1

类 以及它们在 python 中的实例使用类似字典的数据结构来存储信息。

因此,对于每个 class 定义,将分配一个字典,其中将存储 class 级别信息(class 变量)。对于该特定 class 的每个实例,将分配一个单独的字典(self),其中将存储实例特定信息(实例变量)。

所以现在下一个问题是: 如何查找特定名称??

这个问题的答案是,如果您通过某个实例访问名称,将首先搜索实例特定的字典,如果在那里找不到名称,那么将搜索 class 字典为了那个名字。因此,如果在两个级别定义相同的值,则前一个将被覆盖。

请注意,当您编写 d['key'] = val 时,其中 d 是字典,如果 'key' 不存在,则会自动添加到字典中。否则当前值将被覆盖。在阅读进一步的解释之前请记住这一点。

现在让我们看一下您用来描述问题的代码:

MyClass1

class MyClass1:
    q=1
    def __init__(self,p):
        self.p=p
    def AddSomething(self,x):
        self.q = self.q+x

1. my = Myclass1(2) #create new instance and add variables to it.

    MyClass = {"q" : 1}
    my = {"p" : 2}

2. my.p    # =2, p will be taken from Dictionary of my-instance.

3. my.q    # =1, q will be takn from MyClass dict. (Not present in dictionary of my-instance).

4. my.AddSomething(7) # This method access the value of q (using self.q) first 
                      # which is not defined in my dict and hence will be taken
                      # from dictionary of MyClass. After the addition operation,
                      # the sum is being stored in self.q. Note that now we are
                      # adding the name q to Dictionary of my-instance and hence                   
                      # a new memory space will be created in Dictionary of my-instance
                      # and the future references to self.q will fetch the value
                      # of self.q from dictionary of my-instance.

    MyClass = {"q" : 1}
    my = {"p" : 2, "q" : 8}

5. my.q   # =8, q now is available in dictionary of my-instance.