面向过程
核心是过程二字,就是做事的步骤,即先干什么,再干什么,最后干什么
优点:复杂的问题简单化,进而流程化
缺点:扩展性差
应用场景:对扩展性要求较低的地方
面向对象
核心是对象二字:
1.在程序中:
盛放数据属性和功能的容器
2.现实生活中:
特征与技能的结合体(一切皆对象)
优点:扩展性强,维护性强
缺点:编程复杂度高了
应用场景:对扩展性较高的地方
类的定义和对象的产生
类:一系列对象相似的特征和相似的技能的结合体
1.程序中:
必须先定义类,然后调用类产生对象
2.现实生活中:
先有对象,再有类
定义类:
class 类名():
# 类体
pass
# 注意事项:
1.类名可以遵循变量名的命名规范
大驼峰:UserName(类名中推荐使用)
小驼峰:userName
class Student(): school='SH' # 调用类的时候,自动触发的函数 def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender stu=Student('ldb',18,'male') print(stu.__dict__) print(stu.name) ''' 定义类发生几件事情? 1.立即执行类体代码 2.产生一个类的名称空间,把类里面的数据属性和方法名都丢到类的名称空间去:{} 3.把类的名称空间绑定给__dict__,类名.__dict__ 查看函数的名称空间? locals() 查看局部的 globals() 查看全局的 调用类发生了几件事? 1.产生一个空对象 2.调用了Student.__init__(stu),把自己当成第一个参数传到函数里面 3.得到一个初始化结果,并返回给对象 4.初始化方法__init__不能有返回值,如果非要返回,返回None '''
属性的查找顺序
类属性:在类中定义的属性称为类属性
对象属性:对象自己独有的属性
1.类属性查找
查:print(Student.school) 增加:Student.city='china' 改:Student.city='UFO' 删除:del Student.school
类中的方法类可以调用,对象也可以调用
Student.choose_course(self,name)
***类中的方法类来调用,参数有几个就要传几个,不会自动传递***
2.对象属性查找
查:stu.name 增加:stu.x='x' 改:stu.x='y' 删除:del stu.x
对象调用方法,其实是在调用类中的方法
stu.choose_course(self) # 对象调用方法,会把自己当成第一个参数“自动”传到函数里面
***对象调用属性,先从自己的名称空间中查找,如果没有找到,再去产生该对象的类中查找***
案例:定义一个类,产生一堆对象,统计产生了多少个对象
class Student(): school='SH' count=0 # 专门用来计数 def __init__(self,name,age): self.name=name self.age=age Student.count+=1 # self.__class__.count+=1 stu=Student('ldb',18) stu1=Student('marry',24) stu2=Student('jack',26) print(stu.count) # 3 print(stu1.count) # 3 print(stu2.count) # 3
绑定方法
# 绑定给对象的 class Student(): def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender # 绑定给对象的方法,对象来调用,会把自己当成第一个参数传到函数里面self def tell_info(self): print('name:%s,age:%s,gender:%s' % (self.name,self.age,self.gender)) stu=Student('ldb',18,'male') stu.tell_info() # 绑定给类的 class Mysql(): def __init__(self,ip,port): self.ip=ip self.port=port @classmethod # 该方法绑定给类了,以后由类来调用,会自动把类名当成第一个参数传过来:cls def from_conf(cls): obj=cls(settings.IP,settings.PORT) return obj Mysql.from_conf()
非绑定方法
既不绑定给类,也不绑定给对象
class Student(): school='SH' def __init__(self,name,age): self.name=name self.age=age @staticmethod # 静态方法 def create_id(): import uuid return uuid.uuid4() stu=Student('ldb',18) print(stu.create_id())
如何隐藏属性
''' 1.在类定义阶段,发生了语法上的变形_类名__属性名 2.隐藏对外不对内 3.只有在类定义阶段发生变形,其他情况都不发生变形 为什么要隐藏:类里面的隐藏属性,类外部可以使用,但是目的不是让类外部使用的,类外部要是想用,在类内部开发接口进行访问 可以达到对外部数据的严格控制 ''' class Student(): __school='SH' # _Student__school _类名__属性名 city='China' def __init__(self,name,age): self.__name=name self.age=age def __tell_info(self): # _Student__tell_info print('name:%s,age:%s' %(self.__name,self.age)) def get_school(self): return self.__school # self._Student__school def set_school(self,v): if type(v) is not str: print('数据类型不合法') return self.__school=v stu=Student('ldb',18) print(stu.set_school(123)) # 数据类型不合法
property装饰器
class Student(): __school='SH' def __init__(self,name,age): self.__name=name self.age=age @property # 把方法伪装成属性 def name(self): return "name:%s" % self.__name @name.setter def name(self,v): if type(v) is not str: print('数据类型不合法') return self.__name=v @name.deleter def name(self): print('不让删') stu=Student('ldb',18) print(stu.name) # name:ldb stu.name=123 print(stu.name) # 数据类型不合法 del stu.name # 不让删 ''' BMI指数是用来衡量一个人的体重与身高对健康影响的一个指标,计算公式为: 体质指数(BMI)=体重(kg)÷身高^2(m) EX:70kg÷(1.75x1.75)=22.86 ''' class Bmi(): def __init__(self,height,weight): self.height=height self.weight=weight @property def get_bmi(self): return self.weight/(self.height ** 2) bmi=Bmi(1.72,54) print(bmi.get_bmi)