1、类和对象
a、类定义:对一组具有相同属性和方法的事物的抽象。
举例:人类、鸟类、学生类
语法结构:
class 类名(父类):
"""
类的说明
"""
类体
代码案例:
class Student(object):
"""
学生类
"""
age = 20
===>类属性
def get_info(self):
===>类方法
return '学生类'
b、对象的定义:类的实例
举例:小强、小明养的那只鸟、韩梅梅
语法:
创建:对象名 = 类名() ===>其实是调用了该类的构造方法
调用:对象名.属性 对象名.方法
代码案例:
xiaoqiang = Student()
===>创建对象
xiaoqiang.age
===>对象属性的调用
xiaoqiang.get_info()
===>对象方法的调用
使用场景:工程中。代码规范、高内聚低耦合、更符合人的思维。Python放在AI中更多的使用面向过程的思想,算法原型出的快,此时使用OO反倒不方便。等原型稳定后,再改为OO比较合理。
2、封装
使用场景:不想让外部(类的外部)知道实现细节。细节包含属性怎么定义的,方法中使用了什么算法,以及方法参数的类型和取值范围等等。
实现步骤:
a、私有化成员属性
例:name --> __name
b、set和get方法
例:
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
c、给set和get方法添加安全判断条件
例:
def set_name(self, age)
#判断参数类型
if not isinstance(age, int):
raise TypeError('arg must an int')
#判断参数取值范围
if age < 0 or age > 200:
raise TypeError('agr must between (1,200)’)
#赋值
self.__age = age
3、继承
使用场景:代码或工程中出现了很多类,这些类有一些共同的属性或方法,为了减少代码的重复,此时可以使用继承。
实现步骤:
a、现有父类
例:
class Person(object):
def __init__(self, name):
self.name = name
b、再写子类
例:
class Student(Person):
===>类名后的()中添加父类名称,这就实现了继承
pass
c、子类对象使用从父类继承来的属性和方法
例:
xiaoming = Student('xiaoming')
===>强迫使用继承自父类的init方法
print(xiaoming.name)
===>可以使用继承自父类的属性
注意事项:
a、父类中的私有成员无法继承
b、父类中的静态方法和类方法?
c、父类中的类属性?
e、super?
4、多态
多态的定义:在OO中出现了方法重名的现象。常见的有方法重写和方法重载两种。
多态的意义:方法实现步骤或者作用类似,基本就可以使用相同的函数名,方便调用者记忆、调用。
a、方法重写:
继承,子类中出现了与父类方法重名的方法,参数列表?
例:
class Animal():
def run():
print('Animal running...')
class Cat(Animal):
def run():
===>出现了方法重名现象
print('Cat running ...')
===>基本上方法体会不同
b、方法重载:
同一个类中。在python中重载基本只发生在内置的基本函数身上。例如__init__、__str__等等。
注意:对于普通函数来说,如果同一类中出现了多个重名的函数,最后出现的函数会覆盖掉前面的函数。python允许添加默认参数和可变参数,所以对普通函数来说,重载没有任何意义。
5、实例属性和类属性
实例属性是属于每一个具体的实例对象的。
类属性是属于该类的所有实例所共有的。
===>可以替换掉全局变量
作用:
类属性主要用来记录该类的相关状态。比如:该类当前拥有了几个实例。
内置的类属性:__dict__ 、__doc__、__name__、__module__、__bases__
6、构造函数和析构函数
a、构造函数
作用:开辟内存空间(__new__)、初始化成员属性值(__init__)
顺序:先new,后init
场景:对于类似于file这样的资源来说,如果把该对象作为属性来用的话,一般在构造函数(__init__)中进行open()操作,这样做的好处是:在普通方法中就直接可以对file进行操作了。
例:
class Save(object):
def __init__(self, filepath):
===>构造方法中打开资源
self.filepath = filepath
self.__file = open(filepath, 'w')
def my_write(self, message):
===>普通方法直接使用资源
?
def __del__(self):
===>析构函数关闭资源
close(self.__file)
b、析构函数
作用:释放资源和内存
场景:当遇到类属性是个资源,且该资源需要在对象结束前释放掉,这个时候才需要重载__del__,并将释放操作放到析构函数中完成。
好处:构造和析构是类对象必须经过的环节,防止资源忘记释放。
7、静态方法和类方法
a、静态方法
作用:比较通用的一些函数,可以使用静态方法的形式放到类里,调用该方法的时候不用再啰嗦的创建该类的对象,而可以直接使用'类名.方法名()'直接调用。。。
例:math.sin()
结构:
class MyMath(object):
@staticmethod
def myabs(x):
if x < 0:
return -x
else:
return x
调用:
MyMath.myabs(-1)
b、类方法
场景:凡是对类属性的操作步骤,都封装到相关的类方法中。
结构:
@classmethod
def test(cls):
print('')