Python的面向对象编程方式学习笔记


Posted in Python onJuly 12, 2016

类与实例
类与实例相互关联着:类是对象的定义,而实例是“真正的实物”,它存放了类中所定义的对象的具体信息。

下面的示例展示了如何创建一个类:

class MyNewObjectType(bases):
   ''' 创建 MyNewObjectType 类'''
   class_suite

关键字是 class,紧接着一个类名。随后是定义类的类代码。这里通常由各种各样的定义和声明组成。新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类,参数 bases 可以是一个(单继承)或多个(多重继承)用于继承的父类。

创建一个实例的过程称作实例化,过程如下(注意:没有使用 new 关键字):

myFirstObject = MyNewObjectType()

类名使用我们所熟悉的函数操作符(()),以“函数调用”的形式出现。然后你通常会把这个新建的实例赋给一个变量。赋值在语法上不是必须的,但如果你没有把这个实例保存到一个变量中,它就没用了,会被自动垃圾收集器回收,因为任何引用指向这个实例。这样,你刚刚所做的一切,就是为那个实例分配了一块内存,随即又释放了它。

类既可以很简单,也可以很复杂,这全凭你的需要。最简单的情况,类仅用作名称空间(namespace)。这意味着你把数据保存在变量中,对他们按名称空间进行分组,使得他们处于同样的关系空间中——所谓的关系是使用标准 Python 句点属性标识。例如,你有一个本身没有任何属性的类,使用它仅对数据提供一个名字空间,让你的类拥有像 C 语言中的结构体(structure)一样的特性,或者换句话说,这样的类仅作为容器对象来共享名字空间。

示例如下:

class MyData(object):
  pass

mathObj = MyData()
mathObj.x = 4
mathObj.y = 5
mathObj.x + mathObj.y
9
mathObj.x \\* mathObj.y
20

方法
在 Python 中,方法定义在类定义中,但只能被实例所调用。也就是说,调用一个方法的最终途径必须是这样的:(1)定义类(和方法);(2)创建一个实例;(3)最后一步,用这个实例调用方法。例如:

class MyDataWithMethod(object): # 定义类
  def printFoo(self): # 定义方法
    print 'You invoked printFoo()!'

这里的 self 参数,它在所有的方法声明中都存在。这个参数代表实例对象本身,当你用实例调用方法时,由解释器传递给方法的,所以,你不需要自己传递 self 进来,因为它是自动传入的。

举例说明一下,假如你有一个带两参数的方法,所有你的调用只需要传递第二个参数。

下面是实例化这个类,并调用那个方法:

> > > myObj = MyDataWithMethod()
> > > myObj.printFoo()
You invoked printFoo()!

\\_init\\(),是一个特殊的方法。在 Python 中, \\init\\() 实际上不是一个构造器。你没有调用“new”来创建一个新对象。(Python 根本就没有“new”这个关键字)。取而代之, Python 创建实例后,在实例化过程中,调用 \\init\\_()方法,当一个类被实例化时,就可以定义额外的行为,比如,设定初始值或者运行一些初步诊断代码——主要是在实例被创建后,实例化调用返回这个实例之前,去执行某些特定的任务或设置。

创建一个类(类定义)

class AddrBookEntry(object):
  '''address book entry class'''
  def __init__(self, nm, ph): # 定义构造器
    self.name = nm       # 设置 name
    self.phone = ph       # 设置 phone
    print 'Created instance for:', self.name

  def updatePhone(self, newph):  # 定义方法
    self.phone = newph
    print 'Updated phone# for: ', self.name

在 AddrBookEntry 类的定义中,定义了两个方法: \\_init\\()和updatePhone()。\\init\\()在实例化时被调用,即,在AddrBookEntry()被调用时。你可以认为实例化是对 \\init\\()的一种隐式的调用,因为传给AddrBookEntry()的参数完全与\\init\\_()接收到的参数是一样的(除了self,它是自动传递的)。

创建实例(实例化)

> > > john = AddrBookEntry('John Doe', '408-555-1212') # 为 John Doe 创建实例
> > > jane = AddrBookEntry('Jane Doe', '650-555-1212') # 为 Jane Doe 创建实例

这就是实例化调用,它会自动调用 \\_init\\()。 self 把实例对象自动传入\\init\\_()。

另外,如果不存在默认的参数,那么传给 \\_init\\_() 的两个参数在实例化时是必须的。

访问实例属性

> > > john
> > > john.name
> > > jane.name
> > > jane.phone

一旦实例被创建后,就可以证实一下,在实例化过程中,我们的实例属性是否确实被 \\_init\\_() 设置了。我们可以通过解释器“转储”实例来查看它是什么类型的对象。

方法调用(通过实例)

> > > john.updatePhone('415-555-1212')  # 更新 John Doe 的电话
> > > john.phone

updatePhone()方法需要一个参数(不计 self 在内):新的电话号码。在 updatePhone()之后,立即检查实例属性,可以证实已生效。

方法与属性的小结
直接上代码,已经在里面有注释了

#coding:utf8

name = 'yangyanxing'
class Test():
  class kevin():
    var1 = '我是内部类'

  name = 'kvein'
  gae = '26'

  def fun1(self):
    print self.name
    print '我是公共方法'
    self.__fun2() #可以通过公有就去来调用私有方法,在调用的过程中可以进行更改

  def __fun2(self):
    print '我是私有方法'

  @classmethod
  def fun3(self): #可以不通过实例来访问这个类方法
    print '#'*40
    print self.name
    print '我是类方法'

  @staticmethod #静态方法,也是可以不通过实例对象就可以访问的方法但是在定义的时候不用加self
  def fun4():
    print Test.name
    print name #这里的name是全局变量
    Test.fun3()
    print '我是静态方法'

print Test.name #公有属性可以直接方法,不用实例化对象
yang = Test() #实例化一个类
interyang = Test.kevin() #实例化一个内部类
yang.fun1() #方法类里面的公共属性
print interyang.var1 # 访问内部类里的属性
Test.fun3()#访问类方法
Test.fun4()
#coding:utf8

class Test():
  var1 = '类的公有属性'
  __var2 = '类的私有属性'

  def fun(self):
    self.var2 = '对象的公有属性' # 这里定义了一个对象的公有属性
    self.__var3 = '对象的私有属性'# 这里定义了一个对象的私有属性
    var4 = '函数的局部变量' #这里定义了一个函数的局部变量,这里面的var4只有在函数内部使用

kevin = Test() #实例了一个对象
yang = Test() #又实例了另外一个对象
print kevin.var1
##print kevin.__var2 #这里将无法访问
kevin.fun()
print kevin.var2 #在没有调用fun函数之前是没有var2的
##print kevin.__var3 对象的私有属性是无法调用的
##print yang.var2 #这里因为没有调用yang的fun方法,所以还是无法访问yang里的var2

创建子类
靠继承来进行子类化是创建和定制新类型的一种方式,新的类将保持已存在类所有的特性,而不会改动原来类的定义。对于新类类型而言,这个新的子类可以定制只属于它的特定功能。除了与父类或基类的关系外,子类与通常的类没有什么区别,也像一般类一样进行实例化。注意下面,子类声明中提到了父类:

class EmplAddrBookEntry(AddrBookEntry):
  '''Employee Address Book Entry class''' # 员工地址簿类
  def __init__(self, nm, ph, id, em):
    AddrBookEntry.__init__(self, nm, ph)
    self.empid = id
    self.email = em

  def updateEmail(self, newem):
    self.email = newem
    print 'Updated e-mail address for:', self.name

现在我们创建了第一个子类, EmplAddrBookEntry。 Python 中,当一个类被派生出来,子类就继承了基类的属性,所以,在上面的类中,我们不仅定义了 \\_init\\_(),UpdateEmail()方法,而且 EmplAddrBookEntry 还从 AddrBookEntry 中继承了 updatePhone()方法。

如果需要,每个子类最好定义它自己的构造器,不然,基类的构造器会被调用。然而,如果子类重写基类的构造器,基类的构造器就不会被自动调用了——这样,基类的构造器就必须显式写出才会被执行,就像我们上面那样,用AddrBookEntry.\\_init\\_()设置名字和电话号码。我们的子类在构造器后面几行还设置了另外两个实例属性:员工ID和电子邮件地址。

注意,这里我们要显式传递 self 实例对象给基类构造器,因为我们不是在该实例中而是在一个子类实例中调用那个方法。因为我们不是通过实例来调用它,这种未绑定的方法调用需要传递一个适当的实例(self)给方法。

使用子类

> > > john = EmplAddrBookEntry('John Doe', '408-555-1212', 42, 'john@spam.doe')
> > > john
> > > john.name
> > > john.phone
> > > john.email
> > > john.updatePhone('415-555-1212')
> > > john.phone
> > > john.updateEmail('john@doe.spam')
> > > john.email
Python 相关文章推荐
Python中的ceil()方法使用教程
May 14 Python
Python内置模块turtle绘图详解
Dec 09 Python
pycharm重置设置,恢复默认设置的方法
Oct 22 Python
利用rest framework搭建Django API过程解析
Aug 31 Python
Pytoch之torchvision.transforms图像变换实例
Dec 30 Python
django中related_name的用法说明
May 20 Python
使用python把xmind转换成excel测试用例的实现代码
Oct 12 Python
多个版本的python共存时使用pip的正确做法
Oct 26 Python
python 实现一个简单的线性回归案例
Dec 17 Python
python基于opencv 实现图像时钟
Jan 04 Python
Python包argparse模块常用方法
Jun 04 Python
PO模式在selenium自动化测试框架的优势
Mar 20 Python
Python使用cookielib模块操作cookie的实例教程
Jul 12 #Python
Python网络编程中urllib2模块的用法总结
Jul 12 #Python
Python中内置的日志模块logging用法详解
Jul 12 #Python
Swift 3.0在集合类数据结构上的一些新变化总结
Jul 11 #Python
浅析Python的web.py框架中url的设定方法
Jul 11 #Python
深入解析Python的Tornado框架中内置的模板引擎
Jul 11 #Python
使用Python的Tornado框架实现一个Web端图书展示页面
Jul 11 #Python
You might like
mysql建立外键
2006/11/25 PHP
PHP 身份证号验证函数
2009/05/07 PHP
PHP编程 SSO详细介绍及简单实例
2017/01/13 PHP
php workerman定时任务的实现代码
2018/12/23 PHP
让网页根据不同IE版本显示不同的内容
2009/02/08 Javascript
Javascript Boolean、Nnumber、String 强制类型转换的区别详细介绍
2012/12/13 Javascript
javascript预加载图片、css、js的方法示例介绍
2013/10/14 Javascript
JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)
2014/08/16 Javascript
JavaScript实现控制打开文件另存为对话框的方法
2015/04/17 Javascript
javascript实现表格增删改操作实例详解
2015/05/15 Javascript
详解JavaScript函数
2015/12/01 Javascript
谈谈我对JavaScript DOM事件的理解
2015/12/18 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
AngularJS自定义控件实例详解
2016/12/13 Javascript
BootStrop前端框架入门教程详解
2016/12/25 Javascript
利用JQuery实现datatables插件的增加和删除行功能
2017/01/06 Javascript
Vue项目中数据的深度监听或对象属性的监听实例
2020/07/17 Javascript
k8s node节点重新加入master集群的实现
2021/02/22 Javascript
[02:22]完美世界DOTA2联赛PWL S3 集锦第一期
2020/12/15 DOTA
详解Python中的多线程编程
2015/04/09 Python
Centos Python2 升级到Python3的简单实现
2016/06/21 Python
Python简单计算数组元素平均值的方法示例
2017/12/26 Python
python生成多个只含0,1元素的随机数组或列表的实例
2018/11/12 Python
python连接、操作mongodb数据库的方法实例详解
2019/09/11 Python
Python如何计算语句执行时间
2019/11/22 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
为什么是 Python -m
2020/06/19 Python
详解Python流程控制语句
2020/10/28 Python
英国最大的美妆产品在线零售商之一:Beauty Bay
2017/09/29 全球购物
纪伊国屋泰国网上书店:Kinokuniya泰国
2017/12/24 全球购物
高中微机老师自我鉴定
2014/02/16 职场文书
客户经理竞聘演讲稿
2014/05/15 职场文书
党员干部民主生活会议批评与自我批评材料
2014/09/20 职场文书
酒店工程部经理岗位职责
2015/04/09 职场文书
清明节文明祭祀倡议书
2015/04/28 职场文书
mysql 8.0.24 安装配置方法图文教程
2021/05/12 MySQL