我在python中很新,在这些日子里,我正在探索课程。我对类中的属性和变量有疑问:在类的主体中仅通过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
。在MyClass1
和MyClass2
中都不会发生错误。
答案 0 :(得分:2)
python中的类及其实例使用字典(如数据结构)来存储信息。
因此,对于每个类定义,将分配将存储类级别信息(类变量)的字典。对于该特定类的每个实例,将分配一个单独的字典(self),其中将存储实例特定信息(实例变量)。
所以现在接下来的问题是: 如何执行特定名称的查找?
回答这个问题的是,如果您通过某个实例访问名称,将首先搜索特定于实例的字典,如果在那里找不到该名称,则将搜索该类字典以查找该名称。因此,如果在两个级别定义相同的值,则将覆盖前一个值。
请注意,当你写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.
答案 1 :(得分:1)
q=1
是一个类属性,与整个类相关联,而不是该类的任何特定实例。使用类本身可以最清楚地访问它:MyClass1.q
。
实例属性直接分配给类的实例,通常在__init__
中通过分配给self
(例如使用self.p = p
),但您可以为实例分配属性在任何时候。
类属性可以读取使用类绑定(MyClass.q
)或实例绑定(my.q
,假设它没有被具有相同属性的实例属性遮蔽名称)。但是,它们只能使用类绑定 set 。使用实例绑定始终设置值会修改实例属性,并在必要时创建它。考虑这个例子:
>>> 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
答案 2 :(得分:0)
此类中q
属性之间最重要的区别在于,在MyClass1
实现中,变量将在此类的所有实例中共享,而在MyClass2
中则为&#39 ; s仅在此特定对象的范围内可见。
一些文档:https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables