类 OOP

来源:互联网 发布:字库制作软件 编辑:程序博客网 时间:2024/06/11 01:19

类和实例的主要差异在于,类是一种产生实例的工厂。

类和模块的一个差异:内存中特定模块只有一个实例(所以我们得重载模块以取得其新代码),每个模块只有一个副本会导入某一个程序中(事实上,我们必须调用reload来更新单个模块对象,反映出来对该模块的修改,这就是原因之一),但是,对类而言,只要有需要,制作多少实例都可以。

Python把隐含的实例传进方法中的第一个特殊的参数,习惯上将其称为self

类连接至其超类的方式是,将超类列在类头部的括号内。其从左至右的顺序会决定树中的次序。

class C1(C2,C3):

如果你使用过C++或Java,就知道Python的self相当于this,但是Python中的self一定是明确写出来的,这样使属性的读取更为明显。

就像简单变量一样,类和实例属性并没有事先声明,而是在首次赋值时它的值才会存在。

从基本的角度来说,类其实就是由函数和其他变量名所构成的包,就像模块。然而,我们从类得到的自动属性继承搜索,支持了软件的高层次的定制,而这是我们通过模块和函数做不到的。

类对象提供默认行为

执行class语句,就会得到类对象。以下是Python类主要特性:

class语句创建类对象并将其赋值给变量名。就像函数def语句,Python class语句也是可执行语句。执行时,会产生新的类对象,并将其赋值给class头部的变量名。此外,就像def应用,class语句一般是在其所在文件导入时执行的。

class语句内的复制语句会创建类的属性。就像模块文件一样,class语句内的顶层的赋值语句(不是在def之内)会产生类对象中的属性。从技术角度来讲,class语句的作用域会变成类对象的属性的命名空间,就像模块的全局作用域一样。执行class语句后,类的属性可由变量名点号运算获取object.name

类属性提供对象的状态和行为。类对象的属性记录状态信息和行为,可由这个类所创建的所有实例共享。位于类中的函数def语句会生成方法,方法将会处理实例。

实例对象是具体的元素

当调用类对象时,我们得到了实例对象。

像函数那样调用类对象会创建新的实例对象。每次类调用时,都会建立并返回新的实例对象。实例代表了程序领域中的具体元素。

每个实例对象继承类的属性并获得了自己的命名空间。由类所创建的实例对象是新命名空间。一开始是空的,但是会继承创建该实例的类对象内的属性。

在方法内对self属性做赋值运算会产生每个实例自己的属性。在类方法函数内,第一个参数(按惯例称为self)会引用正处理的实例对象。对self的属性做赋值运算,会创建或修改实例内的数据,而不是类的数据。

#!/usr/bin/env python# coding=utf-8class FirstClass:    def setdata(self, value):        self.data=value    def display(self):        print(self.data)x=FirstClass()y=FirstClass()x.setdata("King Arthur")y.setdata(3.14)x.display()y.display()x.data="New value"x.display()


在FirstClass的setdata函数中,传入的值会赋给self.data。在方法中,self(按惯例,这是最左侧参数的名称)会自动引用正在处理的实例(x或y),所以赋值语句会把值存储在实例的命名空间,而不是类的命名空间。

我们可以在类的内部或外部修改实例属性。在类内时,通过方法内对self进行赋值运算;而在类外时,则可以通过对实例对象进行赋值运算。虽然比较少见,通过在类方法函数外对变量名进行赋值运算,我们甚至可以在实例命名空间内产生全新的属性。

类通过继承进行定制

在Python中,实例从类中继承,而类继承与超类。

超类列在了类开头的括号中。

类从其超类中继承属性。

实例会继承所有可读取类的属性。

每个object.attribute都会开启新的独立搜索。Python会对每个属性取出表达式进行对类树的独立搜索。这包括在class语句外对实例和类的引用(例如,X.attr),以及在类方法函数内对self实例参数属性的引用。方法中的每个self.attr表达式都会开启对self及其上层的类的attr属性的搜索。

逻辑的修改是通过创建子类,而不是修改超类。在树中层次较低的子类中重新定义超类的变量名,子类就可以取代并定制所继承的行为。

#!/usr/bin/env python# coding=utf-8class FirstClass:    def setdata(self, value):        self.data=value    def display(self):        print(self.data)class SecondClass(FirstClass):    def display(self):        print('Current value = "%s"' % self.data)z=SecondClass()z.setdata(42)z.display()


有时候,我们把这种在树中较低处发生的重新定义的、取代属性的动作称为重载。

类是模块内的属性

如果FirstClass是卸载模块文件内,就可将其导入。单一模块文件内可以有一个以上的类,就像模块内其他语句,class语句会在导入时执行已定义的变量名,而这些变量名会变成独立的模块属性。

#!/usr/bin/env python# coding=utf-8from modulename import FirstClassclass SecondClass(FirstClass):    def display(self):        print('Current value="%s"' % self.data)z=SecondClass()z.setdata(42)z.display()

实际上,Python中的通用惯例指出,类名应该以一个大写字母开头,以使得他们更为清晰。














0 0
原创粉丝点击