面向对象的三大特征:封装、继承、多态
1.封装:屏蔽实现细节,但提供对外调用方式,将功能封装为一个整体,提供简单的调用方式
2.继承:让类与类直接产生父子关系,子类可以拥有父类的方法和属性
3.多态:可以让某个类呈现多种形态
多态的三个条件
#定义人类:可以跳舞,可以玩,在玩的过程中跳舞
#实现多态:老年人跳广场舞
class Person:
"""人的类型"""
def dance(self):
print("跳舞")
def play(self):
self.dance()
class OldMan(Person):
"""老年人类型"""
def dance(self):
print("跳广场舞")
# per1 = Person()
# per1.play()
old = OldMan()
old.play()
用户注册案例
网站可以注册,注册有默认的验证码发送方式
分析
class WebSite:
"""网站类型"""
def register(self,device):
print("开始注册用户。。。")
#调用设备发送验证码的方法
device.send("6666")
input("验证码已发送,请输入:")
print("注册成功")
class Device:
"""设备类型"""
def send(self,code):
print("默认发送验证码:",code)
#用户注册
ws = WebSite()
device = Device()
#发起注册
ws.register(device)
实现多态,用不同的设备注册网站,就使用相应的设备发送验证码
class WebSite:
"""网站类型"""
def register(self,device):
print("开始注册用户。。。")
#调用设备发送验证码的方法
device.send("6666")
input("验证码已发送,请输入:")
print("注册成功")
class Device:
"""设备类型"""
def send(self,code):
print("默认发送验证码:",code)
class Phone(Device):
"""手机注册"""
def send(self,code):
print("通过手机发送验证码:",code)
class Email:
"""邮箱注册"""
def send(self, code):
print("通过邮箱发送验证码:", code)
#用户注册
ws = WebSite()
# device = Device()
phone = Phone()
#发起注册
ws.register(phone)
实例属性:在实例对象中定义的属性(在__init__
中定义的属性)
类属性:在类中定义的属性(类里面,方法外部),多个实例对象共享一份类属性
实例属性的声明和访问
(1) 声明
实例属性的声明,包含在类型的__init__
()初始化方法中,使用self关键字将属性绑定在当前对象上
def __init__(self,name,age):
"""实例属性初始化"""
self.name = name
self.age = age
(2)访问
实例属性在类型内部可以通过self关键字引用,在类型外部可以通过对象引用变量访问和修改
class User:
def __init__(self,name,age):
"""实例属性初始化"""
self.name = name
self.age = age
user = User("zs",18)
print(user.name)
类属性的声明和访问
(1)声明
类里面,方法外部
#数据类型
class Data:
"""数据类型"""
courses_dict = {} #键:课程名称,值:课程对象
#使用实例对象访问
data = Data()
print(data.courses_dict)
#使用类对象访问
print(Data.courses_dict)
(2)访问
类属性能被当前类型的所有对象访问,或者能直接通过类型名称访问
修改
类属性只能被类名称引用修改,不能通过对象的引用变量修改
1.不可变类型:对象名.属性名=属性值 给对象添加属性,而不是进行修改
2.可变类型:如果对象是修改可变类型数据,是真正的修改
? 如果是重新给可变类型变量赋值,则是给对象添加属性
#数据类型
class Data:
"""数据类型"""
# courses_dict = "Python"
courses_dict = ["Python"]
data = Data()
#使用类对象修改课程为"java"
# Data.courses_dict = "java"
#使用实例对象访问
# print(data.courses_dict)
#使用类对象访问
# print(Data.courses_dict)
#使用实例对象修改课程为 "UI"
# data.courses_dict = "UI" #实际上是给实例对象增加属性
#使用实例对象访问
# print(data.courses_dict)
#使用类对象访问
# print(Data.courses_dict)
#如果类属性为可变数据类型,则使用实例对象或者类对象都是真正的修改
# Data.courses_dict.append("java")
#使用实例对象添加
# data.courses_dict.append("java")
#使用实例对象访问
# print(data.courses_dict)
#使用类对象访问
# print(Data.courses_dict)
#实例对象给可变类型重新赋值,则是给该对象添加属性
data.courses_dict = ["Python","java"]
#使用实例对象访问
print(data.courses_dict)
#使用类对象访问
print(Data.courses_dict)
总结
类可以调用实例方法,静态方法,类方法和类属性,但是不能调用实例属性
实例对象可以调用实例方法,类方法,静态方法,类属性,实例属性
实例对象可以调用所有方法和属性,而类除了不能调用实例属性,其他的方法和属性都可以调用
class User:
def __init__(self,name,age):
"""实例属性初始化"""
self.name = name
self.age = age
def introduce(self):
print(f"我叫{self.name},今年{self.age}岁")
user = User("zs",18)
# user.introduce()
# User.introduce(user)
print(User.name) #类对象不能调用实例属性
1、实例方法
实例方法或者叫对象,指的是在类中定义的普通方法
只有实例化对象之后才使用的方法,该方法的第一个参数接收的一定是对象本身!
class User:
def introduce(self):
print("这是实例方法中的代码")
user = User("zs",18)
#通过对象调用实例方法
user.introduce()
类方法:声明在类的内部,方法上使用装饰器@classmethod
第一个参数是当前类型本身,约定俗称是cls;类方法执行访问当前类型的类属性,不能访问任何对象的实例属性;类方法被当前类型调用,也能被实例对象调用
应用场景:当一个方法中只涉及到静态属性的时候可以使用类方法(类方法可以修改类属性)
class Data:
student_dic = {}
@classmethod
def get_student_dic(cls):
"""获取学生信息"""
return cls.student_dic
@classmethod
def set_student_dic(cls,stu_dic):
cls.student_dic = stu_dic
静态方法:是被统一管理在类中的函数,声明在类的内部
1.格式:在方法添加@staticmethod
2.参数:静态方法可以有参数,页可以无参数
3.应用场景:一般用于和类对象以及实例对象无关的代码
4.使用方式:类名.方法名()(或者对象名.方法名())
import time
class Views:
"""界面类型"""
@staticmethod
def get_current_time():
#获取当前时间
now = time.localtime()
return time.strftime("%Y-%m-%d %H:%M:%S",now)
print(Views.get_current_time())
1.构造方法
魔术方法 | 描述 |
---|---|
__new__ (cls)方法 |
创建对象 |
__init__ (self方法 |
初始化对象数据 |
class User:
def __init__(self,name,age):
"""实例属性初始化"""
print("init方法对象初始化")
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
print("new方法开始创建对象")
return object.__new__(cls)
user = User("zs",18)
# print(user.name)
print(user)
对象删除方法
魔术方法 | 描述 |
---|---|
__del__ ()方法 |
对象将要被删除时执行 |
class User:
def __init__(self,name):
"""实例属性初始化"""
print("init方法对象初始化")
self.name = name
def __del__(self):
print("对象将要被删除")
user = User("zs")
print("代码执行结束")
class User:
def __init__(self,name):
"""实例属性初始化"""
print("init方法对象初始化")
self.name = name
def __del__(self):
print("对象将要被删除")
def func():
user = User("zs")
func()
print("代码执行结束")
3.对象的打印
魔术方法 | 描述 |
---|---|
__str__ ()方法 |
打印对象,自定义返回值(字符串) |
__repr__ ()方法 |
对象在组合数据类型中,打印展示自定义的返回值 |
4.对象的函数式调用
魔术方法 | 描述 |
---|---|
__call__ ()方法 |
让对象可以类似函数的方法直接调用执行 |
class User:
def __call__(self, *args, **kwargs):
print("我叫张伟强,请多多关照")
def introduce(self):
print("我叫刘江,请多多关照")
user= User()
# user.introduce()
user()
5.其他
魔术方法 | 描述 |
---|---|
__eq__ ()方法 |
定义==的操作 |
class User:
def __init__(self,name,age):
self.name = name
self.age = age
def __eq__(self, other):
# return self.age==other.age
return self.__dict__==other.__dict__
def __gt__(self, other):
return self.age>other.age
def __cmp__(self, other):
# if self.age>other.age:
# return 1
# elif self.age<other.age:
# return -1
# else:
# return 0
return (self.age>other.age)-(self.age<other.age)
user1 = User("刘江",20)
user2 = User("张伟强",20)
user3 = User("刘江",20)
print(user1==user2) #自定义比较年龄
#自定义比较所有的属性相同,对象才相同
print(user1==user3)
# == 比较的是值,is比较内存地址
lst1 = [1,2,3]
lst2 = [1,2,3]
print(lst1==lst2)
print(lst1 is lst2)
反射:通过字符串的形式操作对象相关的属性 Python中一切事物都是对象(都可以使用反射)
1.反射类的属性和方法 2.反射对象的属性和方法 3.反射模块中的属性和方法
反射方法 | 描述 |
---|---|
hasattr(obj,name) | 判断是否包含名称为name的属性 |
getattr(obj,name) | 获取名称为name的属性的具体数据 |
setattr(obj,name) 较少 | 给名称为name属性设置value值 |
delattr(obj,name) 较少 | 删除名称为name的属性 |
# getattr(obj,name) 获取对象/类中的成员值
# class Teacher:
# dic = {"学生信息":"show_student","老师信息":"show_teacher"}
#
# def __init__(self,name,age):
# self.name = name
# self.age = age
#
# @classmethod
# def func(cls):
# print("--func--")
#
# def show_student(self):
# print("--show_student--")
# def show_teacher(self):
# print("--show_teacher--")
#反射类中的属性和方法
#获取Teacher类中的dic
# print(getattr(Teacher, "dic"))
#获取Teacher类中的func
# ret = getattr(Teacher,"func")
# ret()
#反射对象中的属性和方法
# teacher = Teacher("张老师",30)
#获取name属性
# print(getattr(teacher, "name"))
#获取所有属性
# print(getattr(teacher,"__dict__"))
# ret = getattr(teacher,"show_student")
# ret()
#反射模块中的属性和方法
import test1
#反射模块中的属性
# print(getattr(test1,"name"))
#反射模块中的方法
# func1 = getattr(test1,"func1")
# func1()
# func2 = getattr(test1,"func2")
# func2(666)
#反射模块中的类
# Person = getattr(test1,"Person")
# per = Person()
# per.study()
# hasattr() 检测对象是否有某个成员,返回是布尔值
class Teacher:
dic = {"学生信息":"show_student","老师信息":"show_teacher"}
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def func(cls):
print("--func--")
def show_student(self):
print("--show_student--")
def show_teacher(self):
print("--show_teacher--")
# b = hasattr(Teacher,"dic")
# if b:
# ret = getattr(Teacher,"dic")
# print(ret)
# else:
# print("没有当前属性")
#练习:根据用户输入的key来调用对应的方法
#如:输入"学生信息"-->"--show_student--"
key = input("请输入学生或者老师信息") #学生信息
teacher = Teacher("张老师",30)
b = hasattr(Teacher,teacher.dic.get(key,""))
if b:
func = getattr(teacher,teacher.dic[key])
func()
else:
print("此方法不存在")
setattr和getattr
# setattr() 设置或者添加对象/类中的成员
class Person:
pass
#给Person添加静态属性age
setattr(Person,"age",18)
print(Person.age)
#delattr 删除对象或者类中的成员
per1 = Person()
setattr(per1,"name","张伟强")
print(per1.name)
#删除Person类中的age属性
delattr(Person,"age")
print(Person.age)
单例模式
单例模式确保某一个类只有一个实例存在
当你希望在整个系统中,某个类只能出现一个实例时,就可以使用单例对象
方法:是否是第一次创建对象,如果是首次创建对象,则调用父类__new__
()方法创建对象并返回
? 如果不是第一创建对象,直接返回第一次创建的对象即可
class Shopping:
instance = None #记录创建的对象,None说明是第一次创建对象
def __new__(cls, *args, **kwargs):
#第一次调用new方法,创建对象并记录
#第2-n次调用new方式时,不创建对象,而是直接放回记录的对象
#判断是否是第一次创建对象
if cls.instance==None:
cls.instance = object.__new__(cls)
return cls.instance
else: #不是第一次创建对象
return cls.instance
shop1 = Shopping()
shop2 = Shopping()
print(shop1,shop2)
class Shopping:
instance = None #记录创建的对象,None说明是第一次创建对象
def __new__(cls, *args, **kwargs):
#第一次调用new方法,创建对象并记录
#第2-n次调用new方式时,不创建对象,而是直接放回记录的对象
#判断是否是第一次创建对象
if cls.instance==None:
cls.instance = object.__new__(cls)
return cls.instance
shop1 = Shopping()
shop2 = Shopping()
print(shop1,shop2)
原文:https://www.cnblogs.com/markshui/p/12870360.html