深入讲解Python中面向对象编程的相关知识

Python从第一天开始就是面向对象的语言。正因为如此,创建和使用类和对象是非常地容易。本章将帮助您在使用Python面向对象编程的技术方面所有提高。

如果没有任何以往面向对象(OO)的编程的经验,那么可能要了解一些基本的入门课程就可以了,或者至少某种形式的教程,让你有了解基本概念。

但是,这里会比较少地介绍面向对象编程(OOP):
OOP术语概述

  • 类: 用户定义的原型对象,它定义了一套描述类的任何对象的属性。属性是数据成员(类变量和实例变量)和方法,通过点符号访问。
  • 类变量:这是一个类的所有实例共享的变量。类变量在类,但外面的任何类的方法定义。类变量不被用作经常作为实例变量。
  • 数据成员:保存与类和对象关联的数据的类变量或实例变量。
  • 函数重载:一个以上的行为特定功能的分配。执行的操作所涉及的对象(自变量)的类型不同而不同。
  • 实例变量:所定义的方法内,只属于一个类的当前实例的变量。
  • 继承:类的特点,即都是由它派生其他类的转移。
  • 实例:某一类的一个单独对象。属于类Circle一个obj对象,例如,是类Circle的一个实例。
  • 实例化:创建一个类的实例。
  • Method : 一种特殊的函数,函数在类定义中定义。
  • 对象:这是由它的类中定义的数据结构的唯一实例。一个对象包括两个数据成员(类变量和实例变量)和方法。
  • 运算符重载:一个以上的函数功能,特定的操作符分配。

创建类:

类语句将创建一个新的类定义。类的名称紧跟在关键字class后跟一个冒号,如下所示:

class ClassName:
  'Optional class documentation string'
  class_suite

类有一个文档字符串,它可以通过类名.__ doc__访问。

class_suite由所有定义的类成员,数据属性与函数组件的语句。

例子

下面是一个简单的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

empCount是一个类变量,其值将是这个类的所有实例共享。这可以从类中或外部进行访问,访问形式为 Employee.empCount。

第一个方法__init__()是一种特殊的方法,这就是所谓的类构造函数或当创建该类的一个新实例Python调用的初始化方法。

声明就像正常函数中一样,不同的是第一个参数到每个方法是类的方法。 Python增加了self参数列表;不需要把调用的方法都它列入。

创建实例对象:

要创建一个类的实例,调用类名并传递任何参数给__init__方法接收。

"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)

访问属性:

可以访问使用点运算符来访问对象的属性。而类变量使用类名来访问,如下所示:

emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

现在,把所有的概念放在一起:

#!/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

"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

当执行上面的代码,产生以下结果:

Name : Zara ,Salary: 2000
Name : Manni ,Salary: 5000
Total Employee 2

在任何时候可以添加,删除或修改类和对象的属性:

emp1.age = 7 # Add an 'age' attribute.
emp1.age = 8 # Modify 'age' attribute.
del emp1.age # Delete 'age' attribute.

除了使用正常的语句来访问属性,可以使用以下函数:

  • getattr(obj, name[, default]) : 访问对象的属性。
  • hasattr(obj,name) : 检查一个属性是否存在。
  • setattr(obj,name,value) : 设置一个属性。如果属性不存在,那么它将被创建。
  • delattr(obj, name) : 要删除一个属性。
hasattr(emp1, 'age')  # Returns true if 'age' attribute exists
getattr(emp1, 'age')  # Returns value of 'age' attribute
setattr(emp1, 'age', 8) # Set attribute 'age' at 8
delattr(empl, 'age')  # Delete attribute 'age'

内置的类属性:

每个Python类会继续并带有内置属性,他们可以使用点运算符像任何其他属性一样来访问:

  • __dict__ : 字典包含类的命名空间。
  • __doc__ : 类的文档字符串,或None如果没有定义。
  • __name__: 类名称。
  • __module__: 在类中定义的模块名称。此属性是在交互模式其值为“__main__”。
  • __bases__ : 一个可能是空的元组包含了基类,其在基类列表出现的顺序。

对于上面的类,尝试访问这些属性:

#!/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>}

销毁对象(垃圾回收):

Python的删除不需要的对象(内建类型或类的实例),自动释放内存空间。由Python定期回收的内存块不再使用的过程被称为垃圾收集。

Python的垃圾回收器在程序执行过程中运行,当一个对象的引用计数为零时触发。一个对象的引用计数改变为指向它改变别名的数量。

当它分配一个新的名字或放置在容器(列表,元组或字典)的对象的引用计数增加。当对象的引用计数减少使用 del 删除,其基准被重新分配,或者它的引用超出范围。当一个对象的引用计数变为零,Python会自动地收集它。

a = 40   # Create object <40>
b = a    # Increase ref. count of <40>
c = [b]   # Increase ref. count of <40> 

del a    # Decrease ref. count of <40>
b = 100   # Decrease ref. count of <40>
c[0] = -1  # Decrease ref. count of <40>

当垃圾回收器销毁孤立的实例,并回收其空间一般不会注意到。但是,一个类可以实现特殊方法__del__(),称为析构函数被调用时,该实例将被摧毁。这个方法可以用于清理所用的一个实例的任何非内存资源。
例子:

__del__()析构函数打印实例,它即将被销毁的类名:

#!/usr/bin/python

class Point:
  def __init( self, x=0, y=0):
   self.x = x
   self.y = y
  def __del__(self):
   class_name = self.__class__.__name__
   print class_name, "destroyed"

pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # prints the ids of the obejcts
del pt1
del pt2
del pt3

当执行上面的代码,它产生以下结果:

3083401324 3083401324 3083401324
Point destroyed

注意:理想情况下,应该定义类的单独的文件,那么应该使用import语句将其导入主程序文件。详细请查看Python- 模块章节,导入模块和类的更多细节。
类继承:

不用从头开始,可以通过上面列出的括号父类的新类名后,从一个已经存在的类派生它创建一个类。

子类继承父类的属性,可以使用父类的这些属性,就好像它们是在子类中定义的一样。子类也可以覆盖父类的数据成员和方法。
语法

派生类的声明很像它们的父类; 从基类的列表后给出类名继承:

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

例子

#!/usr/bin/python

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()     # instance of child
c.childMethod()   # child calls its method
c.parentMethod()   # calls parent's method
c.setAttr(200)    # again call parent's method
c.getAttr()     # again call parent's method

当执行上面的代码,产生以下结果:

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

类似的方式,可以按如下继承多个父类的类:

代码如下:

class A:        # define your class A
.....

class B:         # define your calss B
.....

class C(A, B):   # subclass of A and B
.....

可以使用issubclass()或isinstance()函数来检查两个类和实例的关系。

  • issubclass(sub, sup) 如果给定的子类子确实是超sup的子类布尔函数返回true。
  • isinstance(obj, Class) 如果obj是Class类的实例,或者是类的一个子类的实例布尔函数返回true

重写方法:

可以覆盖父类的方法。原因之一重写父的方法,因为可能想在子类特殊或实现不同的功能。
例子

#!/usr/bin/python

class Parent:    # define parent class
  def myMethod(self):
   print 'Calling parent method'

class Child(Parent): # define child class
  def myMethod(self):
   print 'Calling child method'

c = Child()     # instance of child
c.myMethod()     # child calls overridden method

当执行上面的代码,产生以下结果:

Calling child method

基础重载方法:

下表列出了一些通用的功能,可以在类重写中:

 重载运算符:

假设要创建了一个Vector类来表示二维向量,当使用加运算符来增加他们发生了什么?最有可能是Python会屌你。

可以,但是定义__add__方法在类中进行矢量相加,再加上操作符的行为会按预期:
例子:

#!/usr/bin/python

class Vector:
  def __init__(self, a, b):
   self.a = a
   self.b = b

  def __str__(self):
   return 'Vector (%d, %d)' % (self.a, self.b)

  def __add__(self,other):
   return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2

当执行上面的代码,产生以下结果:

Vector(7,8)

数据隐藏:

对象的属性可以是或可以不在类定义外部可见。对于这些情况,可以命名以双下划线前缀属性,这些属性将无法直接让外部可视。
例子:

#!/usr/bin/python

class JustCounter:
  __secretCount = 0

  def count(self):
   self.__secretCount += 1
   print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print counter.__secretCount

当执行上面的代码,产生以下结果:

1
2
Traceback (most recent call last):
 File "test.py", line 12, in <module>
  print counter.__secretCount
AttributeError: JustCounter instance has no attribute '__secretCount'

Python的保护成员通过内部更改名称以包含类名。可以访问这些属性通过object._className__attrName。如果想更换最后一行,那么它会工作如下:

.........................
print counter._JustCounter__secretCount

当执行上面的代码,产生以下结果:

1
2
2
(0)

相关推荐

  • Python使用面向对象方式创建线程实现12306售票系统

    目前python 提供了几种多线程实现方式 thread,threading,multithreading ,其中thread模块比较底层,而threading模块是对thread做了一些包装,可以更加方便的被使用. 面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在函数体之外.类变量通常不作为实例变量使用. 数据成员:类变量或者实例变量用于

  • Python面向对象编程基础解析(一)

    1.什么是面向对象 面向对象(oop)是一种抽象的方法来理解这个世界,世间万物都可以抽象成一个对象,一切事物都是由对象构成的.应用在编程中,是一种开发程序的方法,它将对象作为程序的基本单元. 2.面向对象与面向过程的区别 我们之前已经介绍过面向过程了,面向过程的核心在'过程'二字,过程就是解决问题的步骤,面向过程的方法设计程序就像是在设计一条流水线,是一种机械式的思维方式 优点:复杂的问题简单化,流程化 缺点:扩展性差 主要应用场景有:Linux内核,git,以及http服务 面向对象的程序设计

  • python对象及面向对象技术详解

    本文实例讲述了python对象及面向对象技术.分享给大家供大家参考,具体如下: 1 先看一个例子. 本章将讲解这个例子程序: 文件: fileinfo.py: """Framework for getting filetype-specific metadata. Instantiate appropriate class with filename. Returned object acts like a dictionary, with key-value pairs f

  • 简述Python中的面向对象编程的概念

    面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行.为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度. 而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象

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

    类与实例 类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中所定义的对象的具体信息. 下面的示例展示了如何创建一个类: class MyNewObjectType(bases): ''' 创建 MyNewObjectType 类''' class_suite 关键字是 class,紧接着一个类名.随后是定义类的类代码.这里通常由各种各样的定义和声明组成.新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类,参数 bases 可以是一个(单继承)或多个(

  • 深入讲解Python中面向对象编程的相关知识

    Python从第一天开始就是面向对象的语言.正因为如此,创建和使用类和对象是非常地容易.本章将帮助您在使用Python面向对象编程的技术方面所有提高. 如果没有任何以往面向对象(OO)的编程的经验,那么可能要了解一些基本的入门课程就可以了,或者至少某种形式的教程,让你有了解基本概念. 但是,这里会比较少地介绍面向对象编程(OOP): OOP术语概述 类: 用户定义的原型对象,它定义了一套描述类的任何对象的属性.属性是数据成员(类变量和实例变量)和方法,通过点符号访问. 类变量:这是一个类的所有实

  • 深入了解python中元类的相关知识

    类也是对象 在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段,在python中也是成立的. class ObjectCreator: pass my_object = ObjectCreator() print(my_object) """ 输出结果: <__main__.ObjectCreator object at 0x037DACD0> """ 但是,python的类不止于此,类同样也是一种对象. class Ob

  • Python面向对象之成员相关知识总结

    1.成员 1.1 变量 实例变量,属于对象,每个对象中各自维护自己的数据. 类变量,属于类,可以被所有对象共享,一般用于给对象提供公共数据(类似于全局变量). class Person(object): country = "中国" def __init__(self, name, age): self.name = name self.age = age def show(self): # message = "{}-{}-{}".format(Person.co

  • python中面向对象的注意点概述总结

    目录 一.继承 二.是否继承object类的区别 三.封装 四.类方法.静态方法与属性方法 五.多态 六.python是否存在实质意义上的私有变量? 总结 一.继承 与java的继承不同python支持多继承,如Person类同时继承Animal类和Species类可以这样写: class Animal(object): def __init__(self): pass class Species: def __init__(self): pass class Person(Animal, Sp

  • 讲解Python 中的 with 关键字

    我们中的许多人在 Python 代码中一遍又一遍地看到这个代码片段: with open('Hi.text', 'w') as f: f.write("Hello, there") 但是,我们中的一些人不知道 with 有什么用,以及为什么我们需要在这里使用它.在此阅读中,您将找到关于 with 可解决的几乎所有问题.让我们开始吧! 首先,让我们考虑一下如果不使用 with 关键字我们需要做什么.在这种情况下,我们需要先打开文件并尝试执行 write. 不管成功与否,我们最好在最后关闭

  • 详解Python中键盘鼠标的相关操作

    目录 一.前言 二.pyautogui模块 三.鼠标相关操作 1.鼠标移动 2.获取鼠标位置 3.鼠标点击 4.按松鼠标 5.拖动窗口 6.上下滑动 7.小程序——鼠标操控术2.0 8.小程序——连点器 四.键盘相关操作 1.按键的按松 2.键入字符串 3.热键 4.小程序——轰炸器 5.小程序——520个我爱你 五.尾声 一.前言 恭喜你,学明白类,你已经学会所有基本知识了. 这章算是一个娱乐篇,十分简单,了解一下pyautogui模块,这算是比较好学还趣味性十足的,而且可以做许多小程序. 本

  • 浅谈Python类的单继承相关知识

    一.类的继承 面向对象三要素之一,继承Inheritance 人类和猫类都继承自动物类. 个体继承自父母,继承了父母的一部分特征,但也可以有自己的个性. 在面向对象的世界中,从父类继承,就可以直接拥有父类的属性和方法,这样就可以减少代码.多服用.子类可以定义自己的属性和方法 class Animal: def __init__(self,name): self._name = name def shout(self): print("{} shouts".format(self.__c

  • Python入门学习之类的相关知识总结

    前言 Python是面向对象的程序设计(Object Oriented Programming). 面向对象的程序设计的一条基本原则是: 计算机程序由多个能够起到子程序作用的单元或者对象组合而成. 面向对象的程序设计的一个关键性概念是: 数据以及数据的操作(即函数方法)封装在一起. 这个概念对于接触C++的我来说已经很熟悉了.就是"类"Class. Python完全支持所有面向对象的基本功能,比如: "封装"."继承"."多态"

  • python框架django项目部署相关知识详解

    这篇文章主要介绍了python框架django项目部署相关知识详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一:项目部署的框架 nginx和uWSGI在生产服务器上进行的部署 二:什么是nginx? nginx是一个web服务器. 什么是web服务器? web服务器则主要是让客户可以通过浏览器进行访问,处理HTML文件,css文件,js文件,图片等资源.web服务器一般要处理静态文件.对接服务器. 什么是静态文件? css,js,html

  • Python基础之变量的相关知识总结

    变量全都是引用 跟其他编程语言不同,Python的变量不是盒子,不会存储数据,它们只是引用,就像标签一样,贴在对象上面. 比如: >>> a = [1, 2, 3] >>> b = a >>> a.append(4) >>> b [1, 2, 3, 4] >>> b is a True a变量和b变量引用的是同一个列表[1, 2, 3].b可以叫做a的别名. 比较来看: >>> a = [1, 2,

随机推荐