首页 后端开发 Python教程 Python面向对象

Python面向对象

Nov 23, 2016 pm 02:09 PM
python

Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。

如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。

接下来我们先来简单的了解下面向对象的一些基本特征。

面向对象技术简介

类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。

方法重载:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重载。

实例变量:定义在方法中的变量,只作用于当前实例的类。

继承:即 一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是 模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。

实例化:创建一个类的实例,类的具体对象。

方法:类中定义的函数。

对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

创建类

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

class ClassName:

   'Optional class documentation string'#类文档字符串

   class_suite  #类体

   

类的帮助信息可以通过ClassName.__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__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法

创建实例对象

要创建一个类的实例,你可以使用类的名称,并通过__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  # 添加一个 'age' 属性

emp1.age = 8  # 修改 'age' 属性

del emp1.age  # 删除 'age' 属性

   

你也可以使用以下函数的方式来访问属性:

getattr(obj, name[, default]) : 访问对象的属性。

hasattr(obj,name) : 检查是否存在一个属性。

setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。

delattr(obj, name) : 删除属性。

hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。

getattr(emp1, 'age')    # 返回 'age' 属性的值

setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8

delattr(empl, 'age')    # 删除属性 'age'

   

Python内置类属性

__dict__ : 类的属性(包含一个字典,由类的数据属性组成)

__doc__ :类的文档字符串

__name__: 类名

__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 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':

, 'empCount': 2,

'displayEmployee': ,

'__doc__': 'Common base class for all employees',

'__init__': }

   

python对象销毁(垃圾回收)

同Java语言一样,Python使用了引用计数这一简单技术来追踪内存中的对象。

在Python内部记录着所有使用中的对象各有多少引用。

一个内部跟踪变量,称为一个引用计数器。

当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。

a = 40      # 创建对象  <40>

b = a       # 增加引用, <40> 的计数

c = [b]     # 增加引用.  <40> 的计数

 

del a       # 减少引用 <40> 的计数

b = 100     # 减少引用 <40> 的计数

c[0] = -1   # 减少引用 <40> 的计数

   

垃 圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使 用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(及未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环。

实例

析构函数 __del__ ,__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) # 打印对象的id

del pt1

del pt2

del pt3

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

<p></p>

<p></p><p>以上实例运行结果如下:</p><p></p>

<p></p><pre class="brush:php;toolbar:false"><p></p>

<p>3083401324 3083401324 3083401324</p>

<p>Point destroyed</p>

<p>   </p>

<p></p>

<p>注意:通常你需要在单独的文件中定义一个类,</p>

<p>类的继承</p>

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

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

<p>在python中继承中的一些特点:</p>

<p>1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。</p>

<p>2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数</p>

<p>3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。</p>

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

<p>语法:</p>

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

<p></p>

<p></p>

<p>class SubClassName (ParentClass1[, ParentClass2, ...]):</p>

<p>   'Optional class documentation string'</p>

<p>   class_suite</p>

<p>   </p>

<p></p>

<p>实例:</p>

<p></p>

<p></p>

<p>#!/usr/bin/python</p>

<p> </p>

<p>class Parent:        # define parent class</p>

<p>   parentAttr = 100</p>

<p>   def __init__(self):</p>

<p>      print "Calling parent constructor"</p>

<p> </p>

<p>   def parentMethod(self):</p>

<p>      print 'Calling parent method'</p>

<p> </p>

<p>   def setAttr(self, attr):</p>

<p>      Parent.parentAttr = attr</p>

<p> </p>

<p>   def getAttr(self):</p>

<p>      print "Parent attribute :", Parent.parentAttr</p>

<p> </p>

<p>class Child(Parent): # define child class</p>

<p>   def __init__(self):</p>

<p>      print "Calling child constructor"</p>

<p> </p>

<p>   def childMethod(self):</p>

<p>      print 'Calling child method'</p>

<p> </p>

<p>c = Child()          # 实例化子类</p>

<p>c.childMethod()      # 调用子类的方法</p>

<p>c.parentMethod()     # 调用父类方法</p>

<p>c.setAttr(200)       # 再次调用父类的方法</p>

<p>c.getAttr()          # 再次调用父类的方法</p>

<p>   </p>

<p></p>

<p>以上代码执行结果如下:</p>

<p></p>

<p></p>

<p>Calling child constructor</p>

<p>Calling child method</p>

<p>Calling parent method</p>

<p>Parent attribute : 200</p>

<p>   </p>

<p></p>

<p>你可以继承多个类</p>

<p></p>

<p></p>

<p>class A:        # define your class A</p>

<p>.....</p>

<p> </p>

<p>class B:         # define your calss B</p>

<p>.....</p>

<p> </p>

<p>class C(A, B):   # subclass of A and B</p>

<p>.....</p>

<p>   </p>

<p></p>

<p>你可以使用issubclass()或者isinstance()方法来检测。</p>

<p>issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)</p>

<p>isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。</p>

<p>重载方法</p>

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

<p>实例:</p>

<p></p>

<p></p>

<p>#!/usr/bin/python</p>

<p> </p>

<p>class Parent:        # 定义父类</p>

<p>   def myMethod(self):</p>

<p>      print 'Calling parent method'</p>

<p> </p>

<p>class Child(Parent): # 定义子类</p>

<p>   def myMethod(self):</p>

<p>      print 'Calling child method'</p>

<p> </p>

<p>c = Child()          # 子类实例</p>

<p>c.myMethod()         # 子类调用重载方法</p>

<p>   </p>

<p></p>

<p>执行以上代码输出结果如下:</p>

<p></p>

<p></p>

<p>Calling child method</p>

<p>   </p>

<p></p>

<p>基础重载方法</p>

<p>下表列出了一些通用的功能,你可以在自己的类重写:</p>

<p></p>

<p>序号</p>

<p>方法, 描述 & 简单的调用</p>

<p></p>

<p>1    __init__ ( self [,args...] )<br>构造函数<br>简单的调用方法: obj = className(args)    </p>

<p>2    __del__( self )<br>析构方法, 删除一个对象<br>简单的调用方法 : dell obj    </p>

<p>3    __repr__( self )<br>转化为供解释器读取的形式<br>简单的调用方法 : repr(obj)    </p>

<p>4    __str__( self )<br>用于将值转化为适于人阅读的形式<br>简单的调用方法 : str(obj)    </p>

<p>5    __cmp__ ( self, x )<br>对象比较<br>简单的调用方法 : cmp(obj, x)    </p>

<p>运算符重载</p>

<p>Python同样支持运算符重载,实例如下:</p>

<p></p>

<p></p>

<p>#!/usr/bin/python</p>

<p> </p>

<p>class Vector:</p>

<p>   def __init__(self, a, b):</p>

<p>      self.a = a</p>

<p>      self.b = b</p>

<p> </p>

<p>   def __str__(self):</p>

<p>      return 'Vector (%d, %d)' % (self.a, self.b)</p>

<p>   </p>

<p>   def __add__(self,other):</p>

<p>      return Vector(self.a + other.a, self.b + other.b)</p>

<p> </p>

<p>v1 = Vector(2,10)</p>

<p>v2 = Vector(5,-2)</p>

<p>print v1 + v2</p>

<p>   </p>

<p></p>

<p>以上代码执行结果如下所示:</p>

<p></p>

<p></p>

<p>Vector(7,8)</p>

<p>   </p>

<p></p>

<p>隐藏数据</p>

<p>在 python中实现数据隐藏很简单,不需要在前面加什么关键字,只要把类变量名或成员函数前面加两个下划线即可实现数据隐藏的功能,这样,对于类的实例来 说,其变量名和成员函数是不能使用的,对于其类的继承类来说,也是隐藏的,这样,其继承类可以定义其一模一样的变量名或成员函数名,而不会引起命名冲突。 实例:</p>

<p></p>

<p></p>

<p>#!/usr/bin/python</p>

<p> </p>

<p>class JustCounter:</p>

<p>   __secretCount = 0</p>

<p>  </p>

<p>   def count(self):</p>

<p>      self.__secretCount += 1</p>

<p>      print self.__secretCount</p>

<p> </p>

<p>counter = JustCounter()</p>

<p>counter.count()</p>

<p>counter.count()</p>

<p>print counter.__secretCount</p>

<p>   </p>

<p></p>

<p>Python 通过改变名称来包含类名:</p>

<p></p>

<p></p>

<p>1</p>

<p>2</p>

<p>Traceback (most recent call last):</p>

<p>  File "test.py", line 12, in <module></module></p>

<p>    print counter.__secretCount</p>

<p>AttributeError: JustCounter instance has no attribute '__secretCount'</p>

<p>   </p>

<p></p>

<p>Python不允许实例化的类访问隐藏数据,但你可以使用object._className__attrName访问属性,将如下代码替换以上代码的最后一行代码:</p>

<p></p>

<p></p>

<p>.........................</p>

<p>print counter._JustCounter__secretCount</p>

<p>   </p>

<p></p>

<p>执行以上代码,执行结果如下:</p>

<p></p>

<p>1</p>

<p>2</p>

<p>2</p>

<p><br></p>

 

 

                        </pre>

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

有什么手机APP可以将XML转换成PDF? 有什么手机APP可以将XML转换成PDF? Apr 02, 2025 pm 08:54 PM

无法找到一款将 XML 直接转换为 PDF 的应用程序,因为它们是两种根本不同的格式。XML 用于存储数据,而 PDF 用于显示文档。要完成转换,可以使用编程语言和库,例如 Python 和 ReportLab,来解析 XML 数据并生成 PDF 文档。

xml格式怎么打开 xml格式怎么打开 Apr 02, 2025 pm 09:00 PM

用大多数文本编辑器即可打开XML文件;若需更直观的树状展示,可使用 XML 编辑器,如 Oxygen XML Editor 或 XMLSpy;在程序中处理 XML 数据则需使用编程语言(如 Python)与 XML 库(如 xml.etree.ElementTree)来解析。

有没有免费的手机XML转PDF工具? 有没有免费的手机XML转PDF工具? Apr 02, 2025 pm 09:12 PM

没有简单、直接的免费手机端XML转PDF工具。需要的数据可视化过程涉及复杂的数据理解和渲染,市面上所谓的“免费”工具大多体验较差。推荐使用电脑端的工具或借助云服务,或自行开发App以获得更靠谱的转换效果。

XML修改内容需要编程吗 XML修改内容需要编程吗 Apr 02, 2025 pm 06:51 PM

修改XML内容需要编程,因为它需要精准找到目标节点才能增删改查。编程语言有相应库来处理XML,提供API像操作数据库一样进行安全、高效、可控的操作。

xml格式化工具推荐 xml格式化工具推荐 Apr 02, 2025 pm 09:03 PM

XML格式化工具可以将代码按照规则排版,提高可读性和理解性。选择工具时,要注意自定义能力、对特殊情况的处理、性能和易用性。常用的工具类型包括在线工具、IDE插件和命令行工具。

xml格式如何美化 xml格式如何美化 Apr 02, 2025 pm 09:57 PM

XML 美化本质上是提高其可读性,包括合理的缩进、换行和标签组织。其原理是通过遍历 XML 树,根据层级增加缩进,并处理空标签和包含文本的标签。Python 的 xml.etree.ElementTree 库提供了方便的 pretty_xml() 函数,可以实现上述美化过程。

手机XML转PDF,转换速度快吗? 手机XML转PDF,转换速度快吗? Apr 02, 2025 pm 10:09 PM

手机XML转PDF的速度取决于以下因素:XML结构的复杂性手机硬件配置转换方法(库、算法)代码质量优化手段(选择高效库、优化算法、缓存数据、利用多线程)总体而言,没有绝对的答案,需要根据具体情况进行优化。

怎么在手机上把XML文件转换为PDF? 怎么在手机上把XML文件转换为PDF? Apr 02, 2025 pm 10:12 PM

不可能直接在手机上用单一应用完成 XML 到 PDF 的转换。需要使用云端服务,通过两步走的方式实现:1. 在云端转换 XML 为 PDF,2. 在手机端访问或下载转换后的 PDF 文件。

See all articles