2009年12月15日星期二

python: Class and Object Variables 类变量 实例变量

原帖地址:http://hi.baidu.com/xionghy2008/blog/item/0cb862355e5b4b82a71e1256.html
============================================================

python的类中,类的属性有两种作用域:类变量,实例变量。

类似于java中的static变量与一般变量的区别。

类变量属于整个class所共享,而实例变量则仅仅属于特定对象实例。

类变量和实例变量在操作上的区别

  1. 访问权限

    • 类变量通过类名点操作访问也可以通过实例点操作访问className.var objectName.var

    • 实例变量只可以通过实例名点操作访问 objectName.var

  1. 类变量修改后的表现

    • 通过className.var修改类变量,该类和所有实例所共享的数据将被修改,再次通过类或实例访问得到的将是新的数据。

    • 通过objectName.var修改类变量,其效果将仅仅作用在该实例上,再次通过类或其它实例访问得到的仍然是旧的数据。但这一修改方式将对该类变量实例化,其结果是该实例将得到一个单独的该变量拷贝,此后此对象不再与类共享改名称的变量(实例化一说,是个人对这一现象的定义,还未找到权威描述)

附加测试代码如下

class classA:
    var1=
0
    def __init__(self,text
):
        self.var2=text
#var2 is a instance variable
##       self.var1=init_value #it will make var1 as a instance variable
    def show(self
):
        print self.var1, self.var2
    def set_var1(self, x
):
        self.var1=x


oa=classA(
'a'
)
ob=classA(
'b'
)
print
'---init---'
oa.show
()
ob.show
()
print classA.var1,
'classA'
classA.var1=
1
print
'---after classA.var1=1---'
oa.show
()
ob.show
()
print classA.var1,
'classA'
oa.var1=
2
print
'---after oa.var1=2---'
oc=classA('c'
)
oa.show
()
ob.show
()
oc.show
()
print classA.var1,
'classA'
oa.set_var1(3
)
ob.set_var1(4
)
print
'---after oa.set_var1(3),ob.set_var1(4)---'
oa.show
()
ob.show
()
oc.show
()
print classA.var1,
'classA'
classA.var1=
5
print
'---after classA.var1=5---'
oc=classA('c'
)
oa.show
()
ob.show
()
oc.show
()
print classA.var1,
'classA'

2009年12月10日星期四

python 继承

1,子类可不加定义直接调用父类变量,但此时所有子类共享此变量
2.访问不同父类同名变量
class A:
    def __init__(self):
        self.__data = "A"
class B:
    def __init__(self):
        self.__data = "B"
class C(A,B):
    def __init__(self):
        A.__init__(self)
        B.__init__(self)
        self.data='C'


c=C()
print c._A__data
print c._B__data
print c.data

输出结果:
A
B
C

2009年12月4日星期五

Python的函数参数传递:传值?引用?

作者:winterTTr (转载请注明)

我想,这个标题或许是很多初学者的问题。尤其是像我这样的对C/C++比较熟悉,刚刚进入python殿堂的朋友们

。C/C++的函数参数的传递方式根深蒂固的影响这我们的思维--引用?传值?究竟是那种呢。

呵呵,语言的特性决定了是使用的方法,那么,现在我们来探究一下python的函数参数传递方式。

在开始之前,我们有必要分清一下python的一些基础概念。

首先要说的是:变量 与 对象

在python中,类型属于对象,变量是没有类型的,这正是python的语言特性,也是吸引着很多pythoner的一点。所有的变量都可以理解 是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。所以,希望大家在看到一个python变量的时候,把变量和真正的内存对象分开。

类型是属于对象的,而不是变量。这样,很多问题就容易思考了。

例如:

nfoo = 1 #一个指向int数据类型的nfoo(再次提醒,nfoo没有类型)

lstFoo = [1] #一个指向list类型的lstFoo,这个list中包含一个整数1。

对应于上一个概念,就必须引出另了另一概念,这就是“可更改”(mutable)与“不可更改”(immutable)对象

对于python比较熟悉的人们都应该了解这个事实,在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。那么,这些所谓的可改变和不可改变影响着什么呢?

还是上面的例子:

nfoo = 2

这时,内存中原始的1对象因为不能改变,于是被“抛弃”,另nfoo指向一个新的int对象,其值为2

lstFoo[0] = 2

更改list中第一个元素的值,因为list是可改变的,所以,第一个元素变更为2,其实应该说有一个新int对象被指定给lstFoo 所指向的对象的第一个值,但是对于lstFoo 来说,所指向的对象,并没有变化,就是这个看似void*的变量所指向的对象仍旧是刚刚的那个有一个int对象的list。(听着有点晕吧,仔细琢磨一下 就明白了,嘿)

好了,被我这么填鸭似的复习了一下python的基础知识,改转回题目的问题了,Python的函数参数传递:传值?引用?

对于变量(与对象相对的概念),其实,python函数参数传递可以理解为就是变量传值操作(注意哦,我说的是变量,不是对象 =_= )

接着说例子好了:

def ChangeInt( a ):

a = 10 # change the number

nfoo = 2

ChangeInt(nfoo)

print nfoo #结果是2

这时发生了什么,有一个int对象2,和指向它的变量nfoo,当传递给ChangeInt的时候,按照传值的方式,复制了变量nfoo的值,这样,a就是nfoo指向同一个Int对象了,函数中a=10的时候,发生什么?

(还记得我上面讲到的那些概念么),int是不能更改的对象,于是,做了一个新的int对象,另a指向它(但是此时,被变量nfoo指向的对象,没有发生变化),于是在外面的感觉就是函数没有改变nfoo的值,看起来像C++中的传值方式。

def ChangeList( a ):

a[0] = 10 # change the number

lstFoo = [2]

ChangeList(lstFoo )

print nfoo #结果是[10]

当传递给ChangeList的时候,变量仍旧按照“传值”的方式,复制了变量lstFoo 的值,于是a和lstFoo 指向同一个对象,但是,list是可以改变的对象,对a[0]的操作,就是对lstFoo指向的对象的内容的操作,于是,这时的a[0] = 10,就是更改了lstFoo 指向的对象的第一个元素,所以,再次输出lstFoo 时,显示[10],内容被改变了,看起来,像C++中的按引用传递。

恩,现在是不是对python中的变量和对象的概念有了更深入的理解了呢?

通过我上面的解释,我想大家也可以自己搞定其他类型对象的传递问题了吧。

由参数传递实现的python多态

#实现一个父类,虚构的动物类,并实现一个空的Eat方法
class Animal(object):
def __init__(self):
pass
def Eat(self):
pass

class Chicken(Animal):
def __init__(self):
super(Chicken, self).__init__()
def Eat(self):
print 'the chicken has been eat'

class Dog(Animal):
def __init__(self):
super(Dog, self).__init__()
def Eat(self):
print 'the dog has been eat'

#实现一个调用的方法,这里也用类来实现吧
class Person(object):
def __init__(self,name):
self.name = name
def Feed(self, ped):
ped.Eat()

if __name__ == '__main__':
Kobe = Person('Kobe')#给调用者取个名字吧
pedChicken = Chicken()#建立一个小鸡宠物
pedDog = Dog()#建立一个小狗宠物
Kobe.Feed(PedChicken)#Feed方法根据传入的参数不同调用
Kobe.Feed(pedDog)

这样就形成
发布帖子
了,Feed方法不关心Eat方法实现的细节,只需要通过参数来确定调用哪个方法。这只是python实现多态的一种
这里用到了super,其实在这里例子中没什么用处,只是用来说明子类如何调用父类的方法
Dog类的init方法可以如下实现
def __init__(self):
Animal.__init__(self)
这样也可以,不过多数用super的方法好一点,因为这样至少子类和父类耦合没那么高,把父类的名字写到子类里面毕竟不是什么好事

本文出自 “只想简单” 博客,请务必保留此出处http://gmingzhe.blog.51cto.com/810664/163169

2009年12月2日星期三

VIM的拼写检查



set spell

set spelllang=de