面向对象编程范式3
多态
Python 对实现多态(polymorphism)要求得十分宽松,这意味着我们可以对不同对象调用同名的操作,甚至不用管这些对象的类型是什么。
我们来为三个Quote类设定同样的初始化方法__init__ (),然后再添加两个新方法: who()返回保存的person字符串的值; says()返回保存的words字符串的内容,并添上指定的标点符号。
class Quote():
def __init__ (self, person, words):
self.person = person
self.words = words
def who(self):
return self.person
def says(self):
return self.words + '.'
class QuestionQuote(Quote):
def says(self):
return self.words + '?'
class ExclamationQuote(Quote):
def says(self):
return self.words + '!'
我们不需要改变 QuestionQuote或者ExclamationQuote的初始化方式,因此没有覆盖它们的__init__ ()方法。Python会自动调用父类Quote的初始化方法__init__ ()来存储实例变量person和words,这就是我们可以在子类QuestionQuote和ExclamationQuote的对象里访问self.words 的原因。
创建一些对象:
hunter = Quote('Elmer Fudd', "I'm hunting wabbits")
print(hunter.who(), 'says:', hunter.says()) #返回:Elmer Fudd says: I'm hunting wabbits.
hunted1 = QuestionQuote('Bugs Bunny', "What's up, doc")
print(hunted1.who(), 'says:', hunted1.says()) #返回:Bugs Bunny says: What's up, doc?
hunted2 = ExclamationQuote('Daffy Duck', "It's rabbit season")
print(hunted2.who(), 'says:', hunted2.says()) #返回:Daffy Duck says: It's rabbit season!
三个不同版本的says()为上面三种类提供了不同的响应方式,这是面向对象的语言中多态的传统形式。Python 在这方面走得更远一些,无论对象的种类是什么,只要包含 who() 和says(),你便可以调用它。
我们再来定义一个 BabblingBrook 类,它与我们之前的猎人猎物(Quote 类的后代)什么的没有任何关系:
class BabblingBrook():
def who(self):
return 'Brook'
def says(self):
return 'Babble'
brook = BabblingBrook()
对不同对象执行 who() 和 says() 方法,其中有一个(brook)与其他类型的对象毫无关联:
def who_says(obj):
print(obj.who(), 'says', obj.says())
who_says(hunter) #返回:Elmer Fudd says I'm hunting wabbits.
who_says(hunted1) #返回:Bugs Bunny says What's up, doc?
who_says(hunted2) #返回:Daffy Duck says It's rabbit season!
who_says(brook) #返回:Brook says Babble
模块
1、模块、包和库
我们之前介绍函数是完成特定功能的一段程序,是可复用程序的最小组成单位;类是包含一组数据及操作这些数据或传递消息的函数的集合。模块是在函数和类的基础上,将一系列相关代码组织到一起的集合体。在Python中,一个模块就是一个扩展名为.py的源程序文件。 为了方便调用将一些功能相近的模块组织在一起,或是将一个较为复杂的模块拆分为多个组成部分,可以将这些.py 源程序文件放在同一个文件夹下,按照Python的规则进行管理,这样的文件夹和其中的文件就称为包,库获类库则是功能相关联的包的集合。 模块、包、库和类库在使用上是一样,以下统称为模块。
2、模块导入
在导入一个模块时(import 模块名),Python 首先在当前模块中查找模块,若找不到则在内置的built-in 模块中查找,仍然找不到的话会根据 sys.path 中的目录来寻找这个包中包含的子目录。目录只有包含 __init__.py 文件时才会被认作是一个模块,最简单的就是建立一个内容为空的文件并命名为 __init__.py。 需要注意的是,Python 安装目录下的 Lib 文件夹内存放了内置的标准库。 Lib/site-packages 目录下则存放了用户自行安装的第三方模块(库)。
导入模块一般采用 import 语句,import 语句的语法如下:
import 模块1 [, 模块2[,..., 模块N]]
若只希望导入模块中指定的一部分,可以使用 from…import 语句,其语法如下:
from 模块名 import 类或函数名1 [, 类或函数名2 [, …类或函数名N]]
例如导入上面的 png.py 模块,可以执行: from images.formats import png
3、模块操作
(1)查看模块方法:可以使用 dir() 函数查看一个模块内定义的所有方法,例如查看 Chap11.py内定义的所有方法:
import Chap11
dir(Chap11)
(2)查看模块成员:除了使用 dir() 函数之外,还可以使用 模块.__all__,查看模块(包)内包含的所有成员。
(3)查看模块方法参数:使用help(模块.方法)产看方法参数及使用案例。
实例【海龟绘制正方形】
海龟绘图(Turtle Graphics),出现在1966年的Logo计算机语言。turtle 模块提供面向对象的海龟绘图基本方法:forward()前进、right()右转等。重复四次“前进n步,右转90度”就得到一个正方形。
import turtle as p #导入海龟模块
for i in range(4):
p.right(90)
p.forward(80)
【程序说明】
(1)循环次数4和右转90度是为了保证图形是封闭的。
(2)为了保证是封闭图形,如果循环8次,那么需要右转多少度?
(3)为了保证是封闭图形,如果右转10度,那么循环次数是多少?
运行结果:
画笔运动命令
画笔控制命令
全局控制命令
math模块
Python内置的math模块提供了常用数学函数和数学常量。
数学常数
数值表示函数
函数 | 描述 | 实例 | 结果 |
math.ceil(x) | 返回 >= x 的最小整数 (int) | math.ceil(2.2) | 3 |
math.floor(x) | 返回 <= x 的最大整数 (int) | math.floor(3.6) | 3 |
math.modf(x) | 返回 x 的小数部分和整数部分,两个结果都带有 x 的符号并且是浮点数。 | math.modf(3.4)math.modf(2**52+0.55) | (0.4, 3.0) (0.0, 503599627370497.0) |
math.comb(n, k) | math.comb(3, 2)math.comb(2, 3) | 3 0 | |
math.perm(n, k) | math.perm(3, 2)math.perm(2, 3) | 6 0 | |
math.copysign(x, y) | 返回一个大小为 x 的绝对值,符号同 y 的浮点数 | math.copysign(1.2, -3)math.copysign(-1, 3) | -1.2 1.0 |
math.fabs(x) | |x| | math.fabs(-2) | 2.0 |
math.factorial(n) | n! | math.factorial(4) | 24 |
幂与对数函数
函数 | 描述 | 实例 | 结果 |
math.exp(x) | math.exp(2) | 7.38905609893065 | |
math.log(x[, base]) | 返回以base为底,x 的对数,默认为e | math.log(2)math.log(2, 2) | 0.6931471805599453 1.0 |
math.log2(x) | math.log2(2) | 1.0 | |
math.log10(x) | math.log10(100) | 2.0 | |
math.pow(x, y) | 返回 x 的 y 次幂。math.pow() 将其两个参数都转换为 float 类型。pow() 函数计算精确的整数幂。 | math.pow(2, 3)pow(2, 3) | 8.0 8 |
math.sqrt((x) | 返回 x 的平方根 | math.sqrt(4) | 2.0 |
三角运算函数
函数 | 描述 | 实例 | 结果 |
math.sin(x) | sin(x) | math.sin(math.pi/2) | 1.0 |
math.asin(x) | arcsin(x) | math.asin(1) | 1.5707963267948966 |
math.cos(x) | cos(x) | math.cos(math.pi) | -1.0 |
math.acos(x) | arccosin(x) | math.acos(-1) | 3.141592653589793 |
math.tan(x) | 正切 | math.tan(math.pi/4) | 0.9999999999999999 |
math.atan(x) | 反正切 | math.atan(1) | 0.7853981633974483 |
math.dist(p, q) | 返回两点 p 和 q 之间的欧氏距离 | math.dist((1, 1), (2, 2)) | 1.4142135623730951 |
小结
(1)Python 是面向对象的解释型高级动态编程语言,完全支持面向对象的基本功能和全部特征。 (2)类中所有实例方法都至少包含一个self参数,并且必须是第一个参数,用来表示对象本身. (3)通过对象名调用实例方法时不需要为 self 参数传递任何值。
(4)类成员:方法外定义的变量。
(5)类成员是在类中所有方法之外定义的,而实例成员一般是在构造方法中定义的。
(6)在Python 中,私有化方法也比较简单,即在准备私有化的数据成员或方法的名字前面加两个下划线“__”即可
(7)在类的外部不能直接访问私有成员,也不能直接调用私有方法。
(8)Python支持多继承,如果多个父类中有相同名字的成员,而在子类中使用该成员时没有指定其所属父类名,则Python解释器将从左往右按顺序进行搜索。
(9)多态是指父类的同一个方法在不同子类对象中具有不同的表现和行为。
(10)父类:能够被继承的类,相对的。
(11)子类:继承了某个类的类,子类可以拥有自己的方法。
(12)成员:定义类时用到的变量,包括类成员(类的属性)、实例成员(方法内属性)。
(13)对象:实例化的类,是具体的实体。
(14)子类继承父类的成员和方法。
(15)对象继承了类的成员和方法。
(16)类外部只能访问类成员和带self前缀的方法成员。
(17)同一个类可以生成无数个对象。
(18)对象必须初始化,即成员和方法要赋初值。
(19)子类可以修改父类的方法----重载。
(20)继承分为单继承和多继承: class 子类(父类1,父类2)。
(21)类方法:增加@classmethod修饰符,且第1个参数为cls。
(22)静态方法: 增加@staticmethod修饰符。
原文地址:https://blog.csdn.net/m0_55025444/article/details/143926407
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!