一、面向对象编程:
把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance)实现类的特化(specialization)和泛化(generalization),通过多态(polymorphism)实现基于对象类型的动态分派
面向对象的三大支柱:封装、继承和多态
类的普通定义
class WJL(object):
def __init__(self):
self.__path = 1000
def read(self):
print(self.__path)
if __name__ == "__main__":
wjl = WJL()
wjl.read()
二、类:对象的蓝图和模板,对象是类的实例(类是抽象的概念,而对象是具体的东西)
1、定义类:使用class关键字
2、__init__是一个特殊方法用于在创建对象时进行初始化操作
3、self只是一个印记,不看作为参数
4、在类中调用函数时使用“ . ”
5、括号()表示初始化,即执行__init__语句
6、dir表示查看当前所有可供操作的属性
例题:
加载进度条
import time
class class_name(object):
def jindutiao(self):
for i in range(0,101,2):
time.sleep(0.1)
char_num = i//2 #打印多少个'*'
per_str = '\r%s%% : %s\n' % (i, '*' * char_num) if i == 100 else '\r%s%% : %s'%(i,'*'*char_num)
print(per_str,end='', flush=True)#以一行显示,\r表示光标回到顶端
if __name__=="__main__":
class_name = class_name()
class_name.jindutiao()
读取文件大小写字母
class WJL(object):
def __init__(self,path):
self.path = path
self.count = 0
def read(self):
with open('D://test.txt',mode='r') as f:
readlines = f.readlines()
for readline in readlines:
new_line = readline.strip('\n')
for i in new_line:
if i.isupper():
self.count += 1
print('the upper word is %d'%self.count)
if __name__ == "__main__":
path = 'D:/test.txt'
wjl = WJL(path)
wjl.read()
三、装饰器与修改器
将属性命名以单下划线开头,通过这种方式来暗示属性是受保护的,不建议外界直接访问,那么如果想访问属性可以通过属性的getter(访问器)和setter(修改器)方法进行对应的操作,使用@property包装器来包装getter和setter方法,使得对属性的访问既安全又方便。
class wangjialu(object):
def __init__(self, name, age):
self._name = name
self._age = age
# 访问器 - getter方法
@property
def name(self):
return self._name
# 访问器 - getter方法
@property
def age(self):
return self._age
# 修改器 - setter方法
@age.setter
def age(self, age):
self._age = age
def play(self):
if self._age <= 16:
print('%s正在打扑克.' % self._name)
else:
print('%s正在做家务.' % self._name)
if __name__ == '__main__':
name_ = wangjialu('多啦A梦', 12)
name_.play()
name_.age = 22
name_.play()
注:
如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。
四、静态方法:静态方法和类方法都是通过给类发消息来调用的,也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数
from math import sqrt
class wangjialu(object):
def __init__(self, a, b, c):
self._a = a
self._b = b
self._c = c
@staticmethod
def is_valid(a, b, c):
return a + b > c and b + c > a and a + c > b
def per(self):
return self._a + self._b + self._c
def area(self):
half = self.per() / 2
return sqrt(half * (half - self._a) *
(half - self._b) * (half - self._c))
if __name__ == '__main__':
a, b, c = 3, 4, 5
# 静态方法和类方法都是通过给类发消息来调用的
if wangjialu.is_valid(a, b, c):
t = wangjialu(a, b, c)
print(t.per())
# 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数
# print(Triangle.perimeter(t))
print(t.area())
# print(Triangle.area(t))
else:
print('无法构成三角形.')
封装:python中,属性和方法的访问权限只有俩种,公开的和私有的,若希望属性和方法是私有的就在给属性命名时用俩个下划线作为开头
继承:在已有类的基础上创建新类,就是让一个类从另一个类那里将属性和方法直接继承下来,从而减少重复代码的编写,提供继承信息的我们称之为父类,也叫超类或基类;得到继承信息的我们称之为子类,也叫派生类或衍生类。子类除了继承父类提供的属性和方法,还可以定义自己特有的属性和方法,所以子类比父类拥有的更多的能力
多态:两个子类分别对P父类中的抽象方法进行了重写并给出了不同的实现版本,当我们在main函数中调用该方法时,这个方法就表现出了多态行为