4.1 轻松看对象
1. 面向对象
前面第三章讲到了Python面向过程的编程范式,即函数和模块,它们提高了程序的可用性,而面向对象中的类和对象,也同样有此功用,此外它们两种语法结构加强了程序模拟真实世界的能力。
对于Python,它是一门面向对象的语言,只是它允许程序员以面向过程的方式来使用它。
那么,什么叫面向对象?什么叫面向过程呢?
通俗地解释一下,以如何杀恶龙为例子:
面向过程(Procedure Oriented 简称PO :C......):
1.执行找到剑方法
2.执行招募帮手方法
3.执行找到恶龙方法
4.执行杀死恶龙方法
可以写成 杀龙(找到剑,招募帮手,找到恶龙,杀死恶龙)
过程,过程,自然是注重过程的,也就不存在对象,仅仅通过一个个方法去达成目的。
面向对象(Object Oriented简称OO :C++,JAVA......):
创建对象勇士,赋予对象一些属性和方法,则有 勇士:找到剑方法 招募帮手方法 找到恶龙方法 杀死恶龙方法
然后可以写成 勇士.杀龙(找到剑,招募帮手,找到恶龙,杀死恶龙)
对象,对象,自然是注重对象的,先创建对象,然后用对象执行方法的方式来达成目的。
2. 类
编程中的类其实与我们日常生活中的‘类’的概念差不多,其作用就是根据不同属性和方法将个体(对象)进行分类。用关键字class来定义一个类,通过冒号的强制缩进,便把其中的属性和方法便赋予这个类而形成从属关系。代码说明如下:
class Bird(object): #Bird是类名,object是对象名
feather = True
reproduction = "egg" #feather和reproduction是属性
def chirp(self,sound):
print(sound) #chirp()是方法,其中self是为了在方法内部引用自身
3. 对象
创建对象:
summer = Bird()
小鸡名为summer是对象,且属于鸟类。
对象summer便拥有了属于鸟类的属性和方法。
对属性的引用:对象.属性
对方法的引用:对象.方法()
print(summer.reproduction) #打印出"egg"
summer.chirp("jijijiji") #打印出“jijijiji”
类里面的属性和方法,有时候并不适合类中某些对象,这时我们对类进行拓展,使得对象可以调用方法以说明自身的个性。代码示例如下:
class Bird(object):
def chirp(self,sound):
print(sound)
def set_color(self,color):
self.color = color
summer = Bird()
summer.set_color("yellow")
print(summer.color) #打印“yellow”
对象属性依赖于self,而没办法像类一样,在类下方直接赋值。这时我们就用Python定义的一种特殊方法——魔法方法 来实现对象属性的赋值(初始化),此类方法有如:__init()__、__add()__、__dict()__等等(格式:前后皆有两个下划线)。代码如下:
class Bird(object):
def __init__(self,sound):
self.sound = sound
print("my sound is:", sound)
def chrip(self):
print(self.sound)
summer = Bird("ji")
summer.chrip() #打印出"ji"
此类方法会在创建对象时自动调用。
self不仅可以操作对象属性,还可以让我们在一个方法内部调用同类其他方法:
class Bird(object):
def chrip(self):
print(self.sound)
def chirp_repeat(self,sound,n):
for i in range(n):
self.chirp(sound)
summer = Bird()
summer.chirp_repeat("ji",6) #打印出6个“ji”
4.2继承者们
1. 子类
提到子类,就会想到父类,父子就会有继承关系。类别进一步细分成子类,子类包含了相应对象的一些个性特点,而又继承了主类或父类的属性特征。代码格式呈现:
class 子类名(父类名):
子类的属性(语句块)
继承相当于在父类的属性基础上继续添加个性属性。
2. 属性覆盖
这个也比较好理解,子类相同属性或方法 覆盖 父类相同属性或方法,其实是调用子类时会优先调用自身的属性和方法,无则调用父类的属性和方法。
那么这时候就会出现一种情况,我仅仅想扩展父类的属性或方法,而不是把它全部覆盖,这种情况下我们可以通过super关键字在子类中调用父类中被覆盖的方法。格式有如:
class 子类名(父类名):
def 父类函数/方法名(参数):
super().父类中的方法名()
...
4.3 那些年,错过的对象
1. 列表对象
数据容器——列表也是一个类,即list是列表类的类名。
type():查类型(类型就是对象所属的类的名字)
dir():查类或者对象的所有属性
help():查类的说明文档
pass关键字:一般用在说明文档,说明在该语法结构中“什么也不做”
列表查询方法:
list.count(n):元素n计数
list.index(n):查元素n第一次出现时的下标
列表修改方法:
list.append(元素):在列表最后添加一个新元素
list.sort():排序
list.reverse():颠倒排序
list.pop():去掉最后一个元素,并将该元素返回
list.remove(n):去掉第一次出现的元素n
list.insert(m,n):在下标为m的位置插入元素n
list.clear():清空列表
2. 元组与字符串对象
元组查询方法:
puple.count(n):元素n计数
puple.index(n):查元素n第一次出现时的下标
字符串对象的方法:
str.count():计数子字符串出现次数
str.find() | str.rfind():从左 | 右开始,查找子字符串第一次出现的位置,不含则返回 -1
str.index() | str.rindex:从左 | 右开始,查找子字符串第一次出现的下标,不含则举出错误
str.is(alnum、alpha、digit、title、space、lower、upper)():判断字符串中是否全为字母或数字、全是字母、全是数字、词的首字母全为大写、全为空格、全是小写字母、全是大写字母
str.split | rsplit([sep,[n]]):从左 | 右开始,以空格(可以用其他符号)为分隔符,分割n次
str.join(s):将s中的元素,以str为分隔符进行分割,合并成一个字符串
除上面,还有以下的方法,便不一一赘述了:
str.strip(sub)、str.replace(sub,new_sub)、str.capitalize()、str.lower()、str.upper()、str.swapcase()、str.title()、str.center(width)、str.ljuest(width)、str.rjust(width)
3. 词典对象
词典方法:
dict.keys():返回词典元素的键
dict.values():返回词典元素的值
dict.items():返回词典元素(键值对)
dict.clear():清空整个词典
4.4 意想不到的对象
1. 循环对象
循环对象包含有一个__next__()方法,此方法的目的是生成循环的下一结果。
内置方法iter()可以把一个支持迭代的集合对象转变为循环对象。
for结构等于自动调用__next__()方法。
可借助生成器来自定义循环对象,示例如下:
def shengchengqi():
a = 100
yield a
a = a*8
yield a
yield 1000
for i in shengchengqi():
print(i) #打印出“100 800 1000”
每次调用生成器,会返回yield后面的值,并且终止此次调用,下一次调用时,才会继续返回下一个yield后面的值,即yield有return和break的功用。
2. 函数对象
函数也是一种对象。含有__call__()特殊方法的对象都被当作函数。
3.模块对象
模块也是对象。回归到前面的模块知识,模块即是.py文件,可以把它看作一个对象,其中的函数即是模块对象中的属性或方法。
每个模块对象都有一个__name__属性来记录模块的名字。
4. 异常对象
对于try结构捕捉到的异常也是一个对象。
创建异常对象:
raise ZeroDivisionError()