一、类、实例
在类(面向对象)中 , 一切皆对象,即将现实世界中的内容抽象成程序中的类。例如现实生活中的汽车、飞机、动物、植物、都可以抽象成面向对象中的类。
类是一种封装思想,封装数据以及针对数据的操作,类(计算)是针对数据的操作,运算的是数字,数据,是数据的加减乘除,声明一个类,需要一个关键字:class
声明一个类:类名命名方式为驼峰命名,即单词首字母大写,要有一定的意义。
# 类名: 每个单词首字母都大写, 驼峰名(MyTools) 具有一定意义
# 类注释: 三引号 位于类名下侧
class MyTools:
"""
关于类的说明
"""
# 类名() 可以生成一个类的实例(mt)
mt = MyTools()
mt2 = MyTools()
mt3 = MyTools()
print(type(MyTools), mt, type(mt))
二、封装、继承、多态
面向对象的三大特性:
封装一个人的类 具有名字、 年纪、 性别等实例
class Person:
"""
类封装 数据(name)以及数据对应的操作(get_name, set_name)
"""
def __init__(self, name, age, sex):
print(f"初始化函数执行了")
# print(id(self))
self.name = name
self.age = age
self.sex = sex
def get_age(self):
return self.age
def set_age(self, age):
self.age = age
def get_name(self):
return self.name
def set_name(self, name):
self.name = name
def get_sex(self):
return self.sex
def set_sex(self, sex):
self.sex = sex
def __str__(self):
"""
打印实例 时会打印str函数的返回值
:return: 只能返回字符串
"""
return f"姓名:{self.get_name()}\t年纪:{self.get_age()}\t性别:{self.get_sex()}"
p1 = Person("小明", 15, "男")
# print(id(p1))
print(p1.name)
print(p1.get_name())
p1.set_name("小白")
print(p1.name, p1.get_name())
p1.set_age(25)
print(p1.get_name(), p1.get_age())
p1.set_sex("保密")
print(p1.sex, p1.get_sex())
print(p1)
p2 = Person("小黑", 30, "男")
print(p2)
封装一个人的类 和一个超人 的类 , 人类是超人类的父类,超人类是人类的子类,子类调用实例的方法时,在本身找对应的方法实现 如果找不到 则去父类中找对应的实现。
# """
# 继承
# 父类:定义类时出现在类名后的括号中
# 默认所有类都继承object 可以省略
#
# 子类
#
# 当调用实例的方法时 先在本身找对应的方法实现 如果找不到 则去父类中找对应的实现
# """
#
class Preson(object):
"""
当类Person 没有编写__str__时会直接使用父类的__str__
如果自己定义了__str__ 则使用自己的__str__
"""
def __init__(self, name, age):
self.name = name
self.age = age
def run(self):
return f"遇到危险能逃跑"
def __str__(self):
return f"名字 {self.name}, 年龄 {self.age}"
class SuperPerson(Preson):
def __init__(self, name, age, skill):
super().__init__(name, age)
self.skill = skill
def stave(self):
return f"发动技能'{self.skill}'救人"
def __str__(self):
return f"{super().__str__()},技能是'{self.skill}'"
p1 = Preson("张三", 40)
print(p1, p1.run())
sp1 = SuperPerson("钢铁侠", 30, "战甲合体")
print(sp1, sp1.run(), sp1.stave())
python中并不存在多态,但我们可以借助*agers实现
class Student:
def student(self,name):
print(name)
# 同名函数 上面的student 废掉 无法执行
def student(self,name,age):
print(name,age)
class GoodStudent(Student):
def student(self,*args):
print(args)
class BadStudent(Student):
def student(self,*args,**kwargs):
print(args,kwargs)
s = Student()
s.student("101",24)
gs = GoodStudent()
gs.student("102","男")
bs = BadStudent()
bs.student("103","男",age=23)
三、构造函数、初始化函数、析构函数、转字符串函数
面向对象中的魔法函数:
构造函数:
__new__(cls, *args, **kwargs)
初始化函数:
__init__(self)
析构函数:
def __del__(self)
转字符串函数:
__str__(self)
class Manage:
def __new__(cls, *args, **kwargs):
"""
构造函数用于 创建实例
通过父类 的构造函数来创建实例
:param args:
:param kwargs:
"""
instance = super().__new__(cls)
print(f"创建实例{id(instance)}")
return instance
def __init__(self):
print(f"初始化实例{id(self)}")
"""
初始化方法 初始化self实例
"""
def __str__(self):
"""
一个实例的字符串表示
将实例转化为字符串输出
"""
return "醒醒啦"
def __del__(self):
"""
析构函数: 析构函数用于内存销毁之前的清理工作
当实例不在被使用, 执行实例的析构函数
"""
print(f"析构函数执行了")
m1 = Manage()
print(m1)
四、实例属性、实例方法、类属性、类方法、静态方法
属性:实例属性和类属性
方法:实例方法、类方法、静态方法
五、普通成员、保护成员、私有成员
数据的访问级别:
class Person:
def __init__(self,name,age):
self.__name = name
# __name 私有成员
self._age = age
# _age 保护成员
@property
def name(self):
print("执行获取")
return self.__name
@name.setter
def name(self,name):
print("执行设置")
if 2<=len(name)<=4:
self.__name=name
else:
print("设置不合法")
@property
def age(self):
print("执行年龄获取")
return self._age
@age.setter
def age(self,age):
print("执行年龄设置")
if 0<=age<=100:
self._age=age
else:
print("年龄设置不合法")
p=Person('张三',60)
# print(p.__name) __name 为私有数据 类外不可访问
print(p.name)
p.name = "李四"
print(p.name)
# _age 为保护数据 类外不建议访问
print(p._age)
class PersonManage(Person):
def get_age(self):
return self._age
pm = PersonManage("钢铁侠",50)
print(pm.age,pm.get_age())
六、多继承、单例类
多继承:
class A1:
pass
class A2:
pass
class A(A1,A2):
pass
class B2:
pass
class B1(B2):
pass
def __str__(self):
return "B1"
class B(B1):
pass
def __str__(self):
return "B"
class C:
pass
class D(A,B,C):
pass
d=D()
print(d)
print(D.mro())
运行:
B
[<class '__main__.D'>, <class '__main__.A'>, <class '__main__.A1'>, <class '__main__.A2'>, <class '__main__.B'>, <class '__main__.B1'>, <class '__main__.B2'>, <class '__main__.C'>, <class 'object'>]
D按顺序向父类继承
单例类
class Manage:
instance = None
def __new__(cls, *args, **kwargs):
if not Manage.instance:
Manage.instance = super().__new__(cls)
return Manage.instance
m1 = Manage()
m2 = Manage()
print(id(m1),id(m2),m1 is m2)
class VlueManage(Manage):
pass
vm1 = VlueManage()
vm2 = VlueManage()
print(id(vm1),id(vm2),vm1 is vm2)
运行:
2758377753744 2758377753744 True
2758377753744 2758377753744 True
可知 单例类的实例相同 换句话说 只能创建一个实例