Chinaunix首页 | 论坛 | 博客
  • 博客访问: 217097
  • 博文数量: 20
  • 博客积分: 2016
  • 博客等级: 大尉
  • 技术积分: 660
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-16 00:15
文章分类

全部博文(20)

文章存档

2010年(1)

2008年(19)

我的朋友

分类: LINUX

2008-05-26 21:18:42

All C++ programmer know that there is a useful feature in C++ to share data in all instances of some class, which is called static member variable. Python also provides an intresting feature named class attribute, which can used to emulate this feature in C++.

Let's start our navigation from a simple example:

#! /usr/bin/python

class Counter:
    count = 0

    def Inc(self):
        self.__class__.count += 1
        print "There are %d instance" % (self.__class__.count)

if __name__ == "__main__":
    x = Counter()
    y = Counter()
    print x.count, y.count

    x.Inc()
    print x.count, y.count

    y.Inc()
    print x.count, y.count


In above class, we can see that class Counter owns a unique member variable "count" and a member function to increase the variable, x and y are instances of it. Because the member variable "count" is assigned at the class-level, it is called class attribue. To access the class attributes, python allows user to refer to it through either instances or the class.  Let's look through the result of above program firstly:

0 0
There are 1 instance
1 1
There are 2 instance
2 2
 
We can see that the initial values of instance x and y are all 0, and after calling the member function Inc through instance x and y, the value shall be increased to 1 and 2, and the values of x and y should be kept same. It's worth noting that in function Inc, we use self.__class__.count rather than self.count to modify the value, which denotes that the modification should be executed on the class-level shared data.

Another intresting example is shown as below:

#! /usr/bin/python

class ShareData:
    data = 1

if __name__ == "__main__":
    x = ShareData()
    y = ShareData()

    print "data in x is %d" % (x.data)
    print "data in y is %d" % (y.data)
    print "data in ShareData is %d" % (ShareData.data)

    ShareData.data = 10
    print "data in x is %d" % (x.data)
    print "data in y is %d" % (y.data)
    print "data in ShareData is %d" % (ShareData.data)

    x.data = 20
    print "data in x is %d" % (x.data)
    print "data in y is %d" % (y.data)
    print "data in ShareData is %d" % (ShareData.data)

    ShareData.data = 30
    print "data in x is %d" % (x.data)
    print "data in y is %d" % (y.data)
    print "data in ShareData is %d" % (ShareData.data)


Class ShareData owns a unique class attribute data, and we will try to modify this variable through instance and class. Following is the result of above program:

data in x is 1
data in y is 1
data in ShareData is 1
data in x is 10
data in y is 10
data in ShareData is 10
data in x is 20
data in y is 10
data in ShareData is 10
data in x is 20
data in y is 30
data in ShareData is 30

The initial values of the three types of call are same, and after assigning the value 10 to ShareData.data, the value of x.data and y.data are all set to 10. But if we assign another value 20 to x.data, you can see the member variable data should not keep same value with ShareData.data any more.

This denotes that assignment to an instance's attribute will always change the object, and no other. This assignment will break the shared relation between the instances of a class.

The third example maybe looks more intresting. We will replace the class attribute with a sequence type, such as a list, and you will learn more about the class attribute.

#! /usr/bin/python

class Server:
    Observer = []

    def Register(self, obs):
        self.Observer.append(obs)
        print "current oberservers contain %s" % (self.Observer)

if __name__ == "__main__":
    x = Server()
    y = Server()
    print "The shared oberservers contain %s" % (Server.Observer)

    x.Register("x")
    print "The shared oberservers contain %s" % (Server.Observer)

    y.Register("y")

    print "The shared oberservers contain %s" % (Server.Observer)



And the result of above program should be:

The shared oberservers contain []
current oberservers contain ['x']
The shared oberservers contain ['x']
current oberservers contain ['x', 'y']
The shared oberservers contain ['x', 'y']

From the result, it seems that this example broke the rule summarized in the 2nd example. However, if you consider the case that a list is used as a parameter of a function, you can understand why the list will keep same in all instance. Just add following two statements into above codes:

    z = Server()
    z.Observer = []

And then you will still find the shared observers in the class still contains the string 'x' and 'y'.




阅读(838) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~