拥有的属性、拥有的行为、零散的封装成一个整体。例如:王小二(属性:姓名、年龄、身高...行为:走路、吃饭、放羊...)
python是一门特别彻底的面向对象编程(OOP)的语言( 其它语言包括基本数据类型与对象类型)
他们都是属于一种解决问题的思路。
面向过程:在解决问题的时候,关注的是解决问题的每一个过程(步骤)
面向对象:在解决问题的时候,关注的是解决问题所需要的对象
例如:吃完饭之后洗碗(面向过程:放水、放碗、倒洗洁精、刷、擦干;面向对象:你的技能、你对象的技能...)
1)面向对象和面向过程都是解决问题的一种方式(思想),面向对象是面向过程的一种封装。
2)面向过程编程最重要的是:把一个任务分解成具体的步骤。
3)面向对象编程最重要的是:按照对象的功能进行划分,找到对象确定对象的属性和行为。
1)列举出一个任务具体的实现步骤;
2)试图分离这些实现步骤中的功能代码;
3)将这些功能代码块,划分都某一个对象中;
4)根据这个对象以及对应的行为,抽象出对应的类;
某一个具体对象特征的抽象
根据抽象的类,生产出具体的对象
例如:(类:不良青年 属性:年龄、身高、体重... 行为:吃喝嫖赌...对象:张三、李四、王五...都满足以上的属性和行为)
名称、属性(静态的特征值)、方法(动态的动作)
注意:1)以上属性和方法,都是抽象的概念
2)在产生对象之后,对象才拥有具体的属性值和方法实现
1)类:钱 对象:具体的一块、两块、一百块...
2)类:汽车 对象:奥迪、宝马、奔驰...
对象——>抽象——>类——>实例化——>对象
class Money: #class类名:(类名的首字母需要大写,不要加小括号) pass class renminbi(money): #括号内部表示继承关系
one =Money() #one就是一个对象(通过*类名+一个括号*即可创建一个对象) print(one)
ProcessOn在线绘图(可以绘制流程图)
1)区别:变量是“可以改变的量值”,根据不同的位置存在不同的访问权限(全局变量、局部变量)
属性是“属于某个对象的特性”,只能通过一个对象进行访问
2)判定依据:是否存在宿主
1)添加操作:直接通过对象动态添加——>对象.属性=值
通过类的初始化方法(构造方法)——>int方法
2)查询操作
3)修改操作
4)删除操作
#定义一个类 class Person: pass #根据这个类创建一个对象 p=Person() #给对象p增加属性 p.age=18 p.height=180 #查找当前对象所有的属性(返回一个字典) p.__dict__ #删除一个属性 del p.age
5)注意事项:不同对象之间不能访问其唯一的属性。
1)添加操作:类名.属性=值 ;在类里面写变量名=值
2)查询属性:既可以通过类进行查询,也可以通过对象进行查询
(python对象查找机制:优先到对象自身去查找属性,如果没有找到,则根据class找到对应的类,再在这个类里面进行查找)
3)修改属性:只能通过类名进行修改,不能通过对象进行修改
4)删除操作:只能通过类名进行删除,不能通过对象进行删除
5) 注意事项:类属性的内存存储问题;类属性被各个对象所共享
#在类里面添加属性 class Money: age=18 count=1 pass class Text: sex=male #更改对象所属的类 one=Money() one.__class__=Text #对类的属性的修改 Money.age=22 #删除类的属性 del Money.age
1)方法的概念:描述一个目标的行为动作(比如描述一个人怎么吃、怎么喝...)和函数非常的类似
——>都封装了一系列行为动作
——>都可以被调用之后执行一系列行为动作
——>最主要的区别就是调用的方式不同
#函数 def eat(): print(1) print(2) print(3) eat() #方法 class Person: def eat2(self): print(1) print(2) p=Person() p.eat2()
1)类、对象、实例、实例对象、实例化
2)方法的划分依据
实例方法:默认第一个参数需要接收到一个实例;
类方法:默认第一个参数需要接收到一个类;
静态方法:静静的看着前面两个在装逼,第一个参数啥也不默认接收;
注意:
—>划分的依据是第一个参数必须接收到的数据类型
—>不管是哪一种类型的方法,都是存储在类当中,没有在实例当中的
—>不同类型的调用方式不同
—>重点关注方法的使用层面:语法、不同类型方法的规则、不同类型的方法调用、根据不同的问题设计不同的方法解决问题
3)方法的存储问题
1)标准形式
2)标准调用:使用实例调用实例方法(不用手动传,解释器会自动被调用对象本身传递过来)
注意:如果实例方法没有接收到任何参数,则会报错。
#创建一个类+实例方法 class Person: def eat(self,food): print("在吃饭",food) #标准调用 p=Person() p.eat("土豆") #————>输出:在吃饭,土豆
1)标准形式
2)标准调用:既可以通过类调用,也可以通过实例调用
#创建一个类+类方法 class Person: @classmethod #类方法装饰器 def leifangfa(cls,a): print("这是一个类方法",cls,a) #标准调用(既可以通过类调用,也可以通过实例调用) Person.leifangfa(123) #—————>输出:这是一个类方法,<class'__main__.Person>123
1)标准形式
2)标准调用:既可以通过类调用,也可以通过实例调用
#创建一个类+静态方法 class Person: @staticmethod def jingtai(): print("这是一个静态方法") #标准调用(既可以通过类调用,也可以通过实例调用)
class person: age=0 def shilifangfa(self): print(self.age) print(self.num) @classmethod def leifangfa(cls): print(cls.age) print(cls.num) p=Person() p.num=10 p.shilifangfa() #age和num属性全部能够输出 p.leifangfa() #age属性能够输出,num属性会报错
1)元类:创建类对象的类
2)类的描述:(用于规范编程)
目的:方便自己理清逻辑思路、方便多人合作开发时的沟通、方便生成项目文档
描述方式:在定义类、属性、方法下面一行写注释,使用双引号对(标明效果、 参数、参数含义、参数类型[动态语言参数不确定],是否有默认值, 返回值)
生成项目文档:(不需要把源码全部给别人,先使用help()生成项目)
方式一,使用python内置模块pydoc(参考课程,现学现用)
方式二,使用第三方模块Sphinx、epydoc、doxygen(参考课程,现学现用)
1)私有化属性(对访问范围较大的属性设置一个范围,使其访问范围较小)
可用于数据保护以及数据过滤
注意:python中并没有真正的私有化支持(只是通过名字重整规则加密了),但是可以使用下划线完成伪私有效果(使用其他的手段进行访问); 类属性(方法)和实例属性(方法)遵循相同的规则
公有属性(x):类内部访问——>可以
子类内部访问——>可以
模块内其他位置访问 类访问——>警告
实例访问——>警告
跨模块访问 import——>可以
from 模块 import *——>可以
子类内部访问——>可以
模块内其他位置访问 类访问——>可以
实例访问——>可以
跨模块访问 import——>报错
from 模块 import *——>报错
#file1 _a=6 #file2 from file1 import * print(_a) #受保护会报错 ########################################################################################### #file1 _a=6 __all__=['_a'] #内置属性__all__可用来传输受保护参数 #file2 from file1 import * print(_a) #可以正常访问
子类内部访问——>报错
模块内其他位置访问 类访问——>报错
实例访问——>报错
跨模块访问 import——>报错
from 模块 import *——>报错
注意:也可以使用__all__=['']使其他模块进行访问
_ _x__ 系统内置的特殊属性(例如:__dict__、__count__)
2)只读属性(一个属性【一般指实例属性】只能读取不能写入)
有些属性只限于内部根据不同场景进行修改,而对外界来说不能修改,只能读取。
例如:电脑类的网速属性、网络状态属性。
首先通过“属性前置双下划线”实现,再通过公开的方法进行部分公开。
class Person(object): def __init__(self): #全部隐藏 self.__age=18 #部分公开 @property #主要作用就是可以使用属性的方式来使用这个方法 def age(self): return self.__age p=Person() print(p.age) ''' 经典类与新式类(建议使用新式类) 经典类:没有继承(object) 新式类:有继承(object) 可以通过'__bases__'查询继承类 python2.x 如果定义一个类,没有显示继承自object,那么这个类就是一个经典类。 python3.x 无论有没有显示继承,默认都是一个新式类 ''' ''' @property 装饰器讲解 1.主要作用:将一个些“属性的相关方法(删、改、查)”关联到某一个属性中。常用于定义或管理__X 2.property在新式类中的使用:(代码1) 3.property在经典类中的使用:(代码2)(一般不使用,随用随听) ''' #代码1 class Person(object): def __init_(self): self.__age=18 @property ##########装饰器1:(查) def age(self): return self.__age @age.setter #########装饰器2:(改) def age(self,value) self.__age=value @age.deleter #########装饰器3:(删) def x(self): del self.__age p=Person() print(p.age) print(p.age=90)
class Person: def __setattr__(self,key,value): #当我们通过 实例.属性=值 时,给一个实例增加一个属性或者说修改一个属性值的时候,都会调用这个方法 #在这个方法内部,才会真正把这个属性以及对应的数据存储到__dict__字典里面。 print(key,value) #第一步:判定key是否是我们要设定的只读属性的名称。 if key=='age' and key in self.__dict__.keys(): print('这个属性是只读属性,不能设置数据') #第二部:如果不是只读属性的名称,则真正的给它添加到这个实例里面去。 else: self.__dict__[key]=value
3)内置特殊属性(当定义好一个类或通过这个类创造了一个实例,系统自动的分配了一些可以直接使用的属性,以完成一些小的测试操作或某些应用场景)
__bases__:类的所有父类元组(python是多继承,java是单继承)
__doc__:类的文档字符串
__name__:类名
__module__:类定义所在的模块
__class__:实例对应的类
class Person: age=19 #类属性 def __init__(self): self.name='sz' #利用初始化方法定义一个实例属性 def run(self): print("run") print(Person.__dict__) print(Person.__bases__) print(Person.__doc__) print(Person.__name__) print(Person.__module__) P=Person() print(P.__dict__) print(P.__class__)
1)私有化方法(同于私有化属性:名称重整机制)
当类的内部才使用的方法,且不暴露给外界使用。
2)内置特殊方法
__repr__方法:面向开发人员、python解释器
class Person: def __init__(self,n,a): self.name=n self.age=a def __str__(self): return "这个人的姓名是:%s,这个人的年龄是:%s"%(self.name,self.age) p1=Person("sz",18) p2=Person("zs",19) print(p1) #此时打印的就不再是模块名+类名+内存地址,而是__str__方法,return的返回值 print(p2) print(repr(p1)) #当有__str__方法时,用此方法可打印模块名+类名+内存地址 print(repr(p2))
class Person: def __call__(self,*args,**kwargs): ''' 使用用__call__方法,使得实例化的对象具有被调用的能力。 *args 为元组的形式 **kwargs 为字典形式 这两个参数保证了可以传输任何形式 ''' print("xxx",args,kwarge) pass p=Person p(123,456,name='sz') #若类中没有__call__方法,则会报错;若有__call__方法,则会调用__call__的方法。
#任务:做一个计算器,实现一些基本操作,加减乘除以及打印结果 #面向过程编程,对于连续运算极其复杂,不安全 #设计以及优化思路:包装——>安全性——>能否满足多个同时运算——>是否容错(健壮性) class Cacular: def __int__(self,num): #用于初始化一个类,num是初始化的属性值 if not isinstance(num,int): #Python中的 isinstance() 函数,是Python中的一个内置函数,用来判断一个函数是否是一个已知的类型,类似 type()。 raise TypeError("当前这个数据类型有问题,应该是一个整型数据。") #当程序出现错误,python会自动引发异常,也可以通过raise显示引发异常,并通过TypeError()给出提示语。一旦执行了raise语句,raise后面的语句将不能执行。 self.__result=num #“__”是私密化处理,实例只能调用、查询,不能修改 def jia(self,n): if not isinstance(num,int): raise TypeError("当前这个数据类型有问题,应该是一个整型数据。") self.__result+=n def jian(self,n): if not isinstance(num,int): raise TypeError("当前这个数据类型有问题,应该是一个整型数据。") self.__result-=n def cheng(self,n) if not isinstance(num,int): raise TypeError("当前这个数据类型有问题,应该是一个整型数据。") self.__result*=n def show(self): print("计算的结果是:%d"%self.__result) c1=Cacular(2) c1.jia(6) c1.jian(4) c1.cheng(5) c1.show() ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— #进一步优化思路:以上代码太过冗余,需要简化————>装饰器(不改变原来的代码基础)————>装饰器私有方法 class Cacular: def __check_num_zsq(func): #私有方法的装饰器 def inner(self,n): if not isinstance(num,int): raise TypeError("当前这个数据类型有问题,应该是一个整型数据。") return func(self,n) ######################################################不太明白!!! return inner @__check_num_zsq #装饰器 def __int__(self,num): self.__result=num @__check_num_zsq def jia(self,n): self.__result+=n @__check_num_zsq def jian(self,n): self.__result-=n @__check_num_zsq def cheng(self,n) self.__result*=n def show(self): print("计算的结果是:%d"%self.__result) ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— #增加一个新任务:每一步都实现语音播报功能(类似与开启声音的计算器) #既可以通过安装第三方库实现,也可以通过调用Windows操作系统的接口 #设计以及优化思路:在哪里插入代码——>简化代码————>采用装饰器,不破坏原有的结构(嵌套装饰) import win32com.client class Cacular: def __check_num_zsq(func): #私有方法的装饰器 def inner(self,n): if not isinstance(num,int): raise TypeError("当前这个数据类型有问题,应该是一个整型数据。") return func(self,n) ######################################################不太明白!!! return inner def __say(self,word): spearker=win32com.client.Dispatch("SAPI.ApVoice") #创建一个播报对象 speaker.Speak(word) #通过这个播报器对象,直接播放对应的语音字符串即可 def __creat_say_zsq(word=""): def __say_zsq(func): def inner(self,n): self.__say(word+str(n)) return func(self,n) return inner return __say__zsq @__check_num_zsq #装饰器 @__creat_say_zsq() def __int__(self,num): self.__result=num @__check_num_zsq @__creat_say_zsq("加") def jia(self,n): self.__result+=n @__check_num_zsq @__creat_say_zsq("减去") def jian(self,n): self.__result-=n @__check_num_zsq @__creat_say_zsq("乘以") def cheng(self,n) self.__result*=n def show(self): self.__say("计算的结果是:%d"%self.__result) print("计算的结果是:%d"%self.__result) c1=Caculator(10) c1.jia(6) c1.jian(4) c1.cheng(5) c1.show