首页 > 关于python中类变量和实例变量的问题

关于python中类变量和实例变量的问题

今天学习python中遇见了如下问题:
开始我用的3.4版本:
class Person:
name="aaa"
p1=Person()
p2=Person()
p1.name="bbb"
p2.name(输出显示也为“bbb”!)

我不知是不是自己记错了,我删掉了3.4版本后 改用2.7.8版本,结果

我想问的是,在python的类中,如何控制各个实例共享变量,如何让各个实例拥有各自的类变量(像java中类的变量前加上static 就可让所有实例化对象共享一个变量)

新手,请多多包涵


在变量前面添加self.就是实例变量,比如self.name
如果不添加这个前缀,就是类变量。


pythonpythonjavajavapython有其自己独特的方式。

python中控制实例变量,需要指定self,这个类似java里的this,必须明确指定,不能省略。如果没有制定,则是类变量。类变量是用类名的引用访问,当然实例也可以访问,访问的其实是一个地址的变量。代码如下:

>>> class Person(object):
    name = 'aaa'


>>> p1 = Person()
>>> p2 = Person()
>>> p1.name           # 访问类变量
'aaa'
>>> p2.name           # 访问类变量
'aaa'
>>> Person.name
'aaa'
>>> id(p1.name)
45338952L
>>> id(p2.name)
45338952L
>>> id(Person.name)
45338952L
>>> p1.name is p2.name
True
>>> p1.name is Person.name     # p1.name p2.name Person.name 是同一个对象
True
>>> p2n = p2.name
>>> p1.name = 'bbb'            # 给 p1 这个对象加一个属性,属于实例的属性
>>> id(p1.name)                
45277752L
>>> p1.name is Person.name     # 此时的 p1.name  和之前的不是一个对象,赋值改变了
False
>>> p2.name
'aaa'
>>> Person.name = 'ccc'     # 改成类变量,实际是创建了一个新的类变量对象
>>> id(Person.name)
45277792L
>>> p2.name                 # 指向新的类变量对象
'ccc'
>>> id(p2.name)
45277792L
>>> p2n is Person.name      # 原来的类变量对象,如果这个引用没有了,垃圾回收会回收的
False
>>> 

如果需要每个实例拥有自己的变量,采用 self, python的变量都是对象的引用,赋值的时候,就会创建新的引用。例如:

>>> class Person(object):
    def __init__(self, name='aaa'):
        self.name = name


>>> p1 = Person()
>>> p2 = Person()
>>> p1.name
'aaa'
>>> id(p1.name)
46387448L
>>> p2.name
'aaa'
>>> id(p2.name)
46387448L
>>> p1.name is p2.name
True
>>> p1.name = 'bbb'
>>> id(p1.name)
46326328L
>>> p3 = Person('p3')
>>> id(p3.name)
46387528L
>>> p3.name is p2.name
False
>>> Person.name

Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    Person.name
AttributeError: type object 'Person' has no attribute 'name'
>>> p2.name = 'p3'
>>> id(p2.name)
46387528L
>>> p3.name is p2.name
True
>>> p2.name = 'p2'
>>> p3.name
'p3'
>>> p3.name is p2.name
False
>>> 

你一定是记错了。按你说的你在 py3 中应该是这么写的Person.name = 'bbb'

【热门文章】
【热门文章】