python中创建类属性

来源:互联网 发布:阿里高校数据 编辑:程序博客网 时间:2024/04/29 09:58

python中创建类属性

类是模板,而实例则是根据类创建的对象。

绑定在一个实例上的属性不会影响其他实例,但是,类本身也是一个对象,如果在类上绑定一个属性,则所有实例都可以访问类的属性,并且,所有实例访问的类属性都是同一个!也就是说,实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。

定义类属性可以直接在 class 中定义:

class Person(object):    address = 'Earth'    def __init__(self, name):        self.name = name

因为类属性是直接绑定在类上的,所以,访问类属性不需要创建实例,就可以直接访问:

print Person.address# => Earth

对一个实例调用类的属性也是可以访问的,所有实例都可以访问到它所属的类的属性:

p1 = Person('Bob')p2 = Person('Alice')print p1.address# => Earthprint p2.address# => Earth

由于Python是动态语言,类属性也是可以动态添加和修改的:

Person.address = 'China'print p1.address# => 'China'print p2.address# => 'China'

因为类属性只有一份,所以,当Person类的address改变时,所有实例访问到的类属性都改变了。

任务

请给 Person 类添加一个类属性 count,每创建一个实例,count 属性就加 1,这样就可以统计出一共创建了多少个 Person 的实例。

class Person(object):    count = 0    def __init__(self, name):        self.name = namep1 = Person('Bob')Person.count = Person.count + 1print Person.countp2 = Person('Alice')Person.count = Person.count + 1print Person.countp3 = Person('Tim')Person.count = Person.count + 1print Person.count
输出结果  1  2  3

python中类属性和实例属性名字冲突怎么办

修改类属性会导致所有实例访问到的类属性全部都受影响,但是,如果在实例变量上修改类属性会发生什么问题呢?

class Person(object):    address = 'Earth'    def __init__(self, name):        self.name = namep1 = Person('Bob')p2 = Person('Alice')print 'Person.address = ' + Person.addressp1.address = 'China'print 'p1.address = ' + p1.addressprint 'Person.address = ' + Person.addressprint 'p2.address = ' + p2.address

结果如下:

Person.address = Earthp1.address = ChinaPerson.address = Earthp2.address = Earth

我们发现,在设置了 p1.address = 'China' 后,p1访问 address 确实变成了 'China',但是,Person.address和p2.address仍然是'Earch',怎么回事?

原因是 p1.address = 'China'并没有改变 Person 的 address,而是给 p1这个实例绑定了实例属性address ,对p1来说,它有一个实例属性address(值是'China'),而它所属的类Person也有一个类属性address,所以:

访问 p1.address ,优先查找实例属性,返回'China'。

访问 p2.address ,p2没有实例属性address,但是有类属性address,因此返回'Earth'。

可见,当实例属性和类属性重名时,实例属性优先级高,它将屏蔽掉对类属性的访问。

当我们把 p1 的 address 实例属性删除后,访问 p1.address 就又返回类属性的值 'Earth'了:

del p1.addressprint p1.address# => Earth

可见,千万不要在实例上修改类属性,它实际上并没有修改类属性,而是给实例绑定了一个实例属性。

任务

请把上节的 Person 类属性 count 改为 __count,再试试能否从实例和类访问该属性。

 

class Person(object):    __count = 0    def __init__(self, name):        Person.__count = Person.__count + 1        self.name = name        print Person.__countp1 = Person('Bob')p2 = Person('Alice')try:    print Person.__countexcept AttributeError:    print "attributeerror"

0 0
原创粉丝点击