python 类学习笔记

一、面向对象技术简介

类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
方法重载:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重载。
实例变量:定义在方法中的变量,只作用于当前实例的类。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

二、创建类
使用class语句来创建一个新类,class之后为类的名称并以冒号结尾,如下实例:

 代码如下 复制代码

class MyClass:
    """A simple example class"""   类文档字符串
    i = 12345   类变量
    def f(self):
        return 'hello world'

MyClass.i 和 MyClass.f 是有效的属性引用,分别返回一个整数和一个方法对象,也可以对类属性赋值,你可以通过给MyClass.i 赋值来修改它, __doc__ 也是一个有效的属性,返回的文档字符串:"A simple example class"

以上创建了一个新的类实例并将该对象赋给局部变量x。

这个实例化操作(“调用”一个类对象)来创建一个空的对象。很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为__init__() 的特殊方法,像下面这样:

 代码如下 复制代码

    def __init__(self):
 
        self.data = []

类定义了 __init__() 方法的话,类的实例化操作会自动为新创建的类实例调用 __init__() 方法。所以在下例中,可以这样创建一个新的实例:

 代码如下 复制代码

x = MyClass()

 

当然, __init__() 方法可以有参数。事实上,参数通过 __init__()传递到类的实例化操作上。例如:

 

 代码如下 复制代码
>>> class Complex:
...     def __init__(self,realpart,imagpart):
...         self.r = realpart
...         self.i = imagpart
...
>>> x = Complex(3.0,-4.5)
>>> x.r, x.i
(3.0, -4.5)

实例对象

现在,我们可以做什么用实例对象?实例对象的操作只有属性引用。有两种有效的属性名,数据属性和方法。

数据属性对应于C中的 Smalltalk的“实例变量”或c++ 中的数据成员。和局部变量一样,数据属性不需要声明;,第一次使用就会被声明。例如,如果x是前面创建的MyClass实例,下面这段代码将打印值16,而不会有任何多余的:

 代码如下 复制代码

x.counter = 1
while x.counter < 10:
    x.counter = x.counter * 2
print x.counter
del x.counter

第二种为实例对象所接受的引用属性是方法。方法是属于一个对象的函数。(在Python中,方法不止是类实例所独有:其它类型的对象也可有方法。例如,链表对象有append,insert,remove,sort等等方法。然而,在这里,除非特别说明,我们提到的方法特指类方法)

实例对象的有效名称依赖于它的类。按照定义,类中所有(用户定义)的函数对象对应它的实例中的方法。所以在我们的例子中,x..f是一个有效的方法引用,因为MyClass.f是一个函数。但x.i不是,因为MyClass.i是不是函数。不过x.f和MyClass.f不同--它是一个  方法对象,不是一个函数对象。

方法对象

方法通常是直接调用的。

x.f()

在MyClass的例子,这将返回字符串'hello world.'。然而,也没必要直接调用方法。xf是一个方法对象,可以存储起来以后再调用。例如:

 代码如下 复制代码

 

xf = x.f
while True:
    print xf()   #会不断www.111cn.net的打印 "hello world".

当调用方法时到底发生了什么?你可能已经注意到当调用 x.f() 时没有引出前面标出的变量,尽管在f()函数的定义中指定了一个参数。这个参数怎么了?如果函数调用中缺少参数,Python会抛出异常--甚至这个参数实际上没什么用……

实际上,你可能已经猜到了答案:方法的特别之处在于实例对象作为函数的第一个参数传给了函数。在我们的例子中,调用x.f() 相当于MyClass.f(x)。通常,以n个参数的列表去调用一个方法就相当于将方法的对象插入到参数列表的最前面后,以这个列表去调用相应的函数。

习惯上,方法的第一个参数命名为 self。这仅仅是一个约定:对Python而言,self 绝对没有任何特殊含义。(然而要注意的是,如果不遵守这个约定,别的Python程序员阅读你的代码时会有不便,而且有些类浏览程序也是遵循此约定开发的。)

类属性中的任何函数对象在类实例中都定义为方法。不是必须要将函数定义代码写进类定义中,也可以将一个函数对象赋给类中的一个变量。例如:

 

 代码如下 复制代码
# Function defined outside the class
def f1(self, x, y):
    return min(x, x+y)
 
class C:
    f = f1
    def g(self):
        return 'hello world'
    h = g

现在 f, g 和 h 都是类C的属性,引用的都是函数对象,因此它们都是C实例的方法--h严格等于g。要注意的是这种习惯通常只会迷惑程序的读者。

通过 self 参数的方法属性,方法可以调用其它的方法:

 代码如下 复制代码

class Bag:
    def __init__(self):
        self.data = []
    def add(self, x):
        self.data.append(x)
    def addtwice(self, x):
        self.add(x)
        self.add(x)

Python内置类属性

__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
__doc__ :类的文档字符串
__name__: 类名
__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于www.111cn.net mymod)
__bases__ : 类的所有父类构成元素(包含了以个由所有父类组成的元组)

Python内置类属性调用实例如下:

 代码如下 复制代码

#!/usr/bin/python
class Employee:
   'Common base class for all employees'
   empCount = 0
 
   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
  
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount
 
   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary
print "Employee.__doc__:", Employee.__doc__
print "Employee.__name__:", Employee.__name__
print "Employee.__module__:", Employee.__module__
print "Employee.__bases__:", Employee.__bases__
print "Employee.__dict__:", Employee.__dict__

执行以上代码输出结果如下:

Employee.__doc__: Common base class for all employees
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount':
<function displayCount at 0xb7c84994>, 'empCount': 2,
'displayEmployee': <function displayEmployee at 0xb7c8441c>,
'__doc__': 'Common base class for all employees',
'__init__': <function __init__ at 0xb7c846bc>}

三、类的继承

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。

需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写作括号里,基本类是在类定义的时候,在元组之中指明的。

在python中继承中的一些特点:

1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。
2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数
3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

语法:

派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:

 代码如下 复制代码

class SubClassName (ParentClass1[, ParentClass2, ...]):
   'Optional class documentation string'
   class_suite

例子:

 代码如下 复制代码

#!/usr/bin/env python
#coding:utf8
class Parent:        # define parent class
   parentAttr = 100
   def __init__(self):
      print "Calling parent constructor"
 
   def parentMethod(self):
      print 'Calling parent method'
 
   def setAttr(self, attr):
      Parent.parentAttr = attr
 
   def getAttr(self):
      print "Parent attribute :", Parent.parentAttr
 
class Child(Parent): # define child class
   def __init__(self):
      print "Calling child constructor"
 
   def childMethod(self):
      print 'Calling child method'
 
c = Child()          # 实例化子类
c.childMethod()      # 调用子类的方法
c.parentMethod()     # 调用父类方法
c.setAttr(200)       # 再次调用父类的方法
c.getAttr()          # 再次调用父类的方法

以上代码执行结果如下:

Calling child constructor
Calling child method
Calling parent method
Parent attribute : 200

重载方法

如果你的父类方法的功能不能满足你的需求,你可以在子类重载你父类的方法:

实例:

 

 代码如下 复制代码

#!/usr/bin/python
 
class Parent:        # 定义父类
   def myMethod(self):
      print 'Calling parent method'
 
class Child(Parent): # 定义子类
   def myMethod(self):
      print 'Calling child method'
 
c = Child()          # 子类实例
c.myMethod()         # 子类调用重载方法

执行以上代码输出结果如下:

Calling child method

时间: 2024-11-13 04:22:44

python 类学习笔记的相关文章

python函数学习笔记

#!/usr/bin/env python #个人学习笔记,无其他用途 def add(x=9,y=10): if x>y: a=x+y print "x+y" return a if x<y: a=y-x print "y-x" return a if x==y: a=x*y print "x*y" return a print add(2,3) print add(5,4) print add(6,6) 将一个数组的值传递给函数

python基础学习笔记(九)

python异常   python用异常对象(exception object)来表示异常情况.遇到错误后,会引发异常.如果异常对象并未被处理或捕捉,程序就会用所谓的 回溯(Traceback, 一种错误信息)终止执行: >>> 1/0 Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> 1/0 ZeroDivisionError: integer

python多线程学习笔记

之前用linux shell写过多线程统计youku网站会员的,现在用python再实现一遍,做为学习笔记备注. Python多线程可以通过导入thread模块,来使用thread中的函数,或者通过继承threading类来创建线程. 每个进程都拥有自己的地址空间,内存,数据栈以及记录其运动轨迹的辅助数据. python代码的执行主要由python虚拟机(也叫解释器GIL主循环)来控制,对python虚拟机的访问由python全局解释器锁GIL来控制,正是这个锁保证了任一时刻只有一个线程在运行.

简明Python教程学习笔记_6_面向对象编程

简介 类和对象是面向对象编程的两个主要方面.类创建一个新类型,而对象这个类的 实例 .这类似于你有一个int类型的变量,这存储整数的变量是int类的实例(对象). 类(Class)::用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 对象:          通过类定义的数据结构实例.对象包括两个数据成员(类变量和实例变量)和方法. 实例化:      创建一个类的实例,类的具体对象.方法:          类中定义的函数. (方法和函数在

Python 爬虫学习笔记之单线程爬虫_python

介绍 本篇文章主要介绍如何爬取麦子学院的课程信息(本爬虫仍是单线程爬虫),在开始介绍之前,先来看看结果示意图 怎么样,是不是已经跃跃欲试了?首先让我们打开麦子学院的网址,然后找到麦子学院的全部课程信息,像下面这样 这个时候进行翻页,观看网址的变化,首先,第一页的网址是 http://www.maiziedu.com/course/list/, 第二页变成了 http://www.maiziedu.com/course/list/all-all/0-2/, 第三页变成了 http://www.ma

&lt;深入 Python 3 &gt;学习笔记

可能学习的动力来源于对存在的好奇. 而所谓追求真善美,只是学习过程中的某一单维折射而已. 而学习的原理在于重复关注到使之成为思维惯性吧. PYTHON,我越来越记住它啦. 正如所有程序语言都涉及数据类型,数据结构,算法,标准库,扩展库,与系统API互动,,当然,它也不例外, <深入 Python 3 >电子版,URL:http://dipyzh.bitbucket.org/ 我也慢慢作笔记~: 在 Python 中, 每个值都属于某种数据类型,但却不用对声明变量的数据类型.它是怎么做到呢?Py

简明Python教程学习笔记_4_数据结构

在Python中有三种内建的数据结构--列表.元组和字典. 列表 list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个 序列 的项目.假想你有一个购物列表,上面记载着你要买的东西,你就容易理解列表了.只不过在你的购物表上,可能每样东西都独自占有一行,而在Python中,你在每个项目之间用逗号分割. 列表中的项目应该包括在方括号中,这样Python就知道你是在指明一个列表.一旦你创建了一个列表,你可以添加.删除或是搜索列表中的项目.由于你可以增加或删除项目,我们说列表是可变的 数据类

简明Python教程学习笔记_8_sys和os

sys模块包含系统对应的功能.我们已经学习了sys.argv列表,它包含命令行参数. #!/usr/bin/python # Filename: cat.py import sys def readfile(filename):  '''Print a file to the standard output.'''  f = file(filename)  while True:     line = f.readline()    if len(line) == 0:      break 

Python 3 学习笔记(二)python基本语法

许多 python 文件的头部都会写上: #!/usr/bin/python 或 #!/usr/bin/python2 或 #!/usr/bin/python3 这句活是必须的么? 如果你用 python xxoo.py 来运行,那么写不写都没关系,如果要用 ./xxoo.py 那么就必须加这行,这行被称为 shebang, 用来为脚本语言指定解释器. 1.编码 3.0之前Python中默认的编码格式是 ASCII 格式,在没修改编码格式时无法正确打印汉字,所以在读取中文时会报错. 解决方法为只