一、面向过程与面向对象的编程
1、面向过程的编程:将复杂问题拆分成若干小问题,按照步骤流程一一解决。也可以说是将复杂问题流程化,为其制定一个固定的实现流程。
优点:复杂问题简单化
缺点:可拓展性差,维护性差。一旦某一步骤出现问题,后续步骤可能无法进行。
应用场景:对扩展性要求较低的软件,如系统内核、脚本程序。
2、面向对象的编程:OOP(Object Oriented Programming)。将程序看作是一堆对象的集合,通过对象之间交互来实现功能。面向对象编程的本质就是使用不同的对象来完成程序。
优点:不用考虑实现步骤,从具体的执行者变成指挥者。扩展性高,对象与整体流程耦合度低;对象与对象之间的耦合度也低。可维护性高。
缺点:相比面向过程,更为复杂,无法预知执行结果。
应用场景:需要较高的扩展性(直接面向消费级用户的程序)。 ? 对于不需要扩展性的程序,使用面向对象的编程思维反而会使问题复杂。
二、类与对象
面向对象思想中最核心的概念就是 类与对象:
对象:一切皆对象,对象指的是具备某些特征与技能的结合体,是具体的物体(如我的手机)。对象本质上就是一种存放数据的容器。
类:类就是类型、类别、分类。类是一个抽象概念,是一些具备相同特征和技能对象的集合体。
类与对象的关系:
类的作用是表示对象与对象之间的相同点,通过类就能大致了解一个对象的特征。
对象是属于某个类的实例。
在现实世界,先有对象,后有类。
在程序中,先有类,后有对象。
类名要按照大驼峰的方式来书写,例如 ThisIsPerson 每个单词首字母都大写。在类中描述对象的特征和行为。
class Person: # 此处没有括号 # 用变量来描述共同特征 name = "alex" sex = "man" age = 22?# 得到对象,通过调用类得到对象,也称之为实例化 或 创建对象obj = Person()print(obj)输出结果为:<__main__.Person object at 0x00000202FF209400> #Person类下的一个对象,内存地址是0x00000202FF209400?# 使用对象的属性(也就是特征)print(obj.name)print(obj.sex)print(obj.age)输出结果为:alexman22?
类中的增删查改:
class Person: name = "alex" print(Person.name) # 查Person.name = "egon" # 改print(Person.name)Person.age = 22 # 增print(Person.age)del Person.name #删?只要对类的属性进行了修改,就会立刻反映给所有对象,而对象却无需修改。
每个对象的内存地址都是不同的,在创建对象时,计算机会申请一个新的内存空间,并将对象中的内容存进去
存储属性的位置有两个,分别是类中和对象中. 当每个对象的某个特征都相同时则放到类中. 当每个对象的某个特征都不同时则放到对象中.
#通过__dict__可以获取一个对象中包含的内容print(obj.__dict__)# 获取类中包含的内容print(Student.__dict__)?当对象中不存在时,会到类中去寻找,类中没有,就去父类中查找。如果对象中存在这个属性,优先访问对象中的属性属性查找顺序:对象---->类
当创建一个类的时候,会产生名称空间,存储类中的名称和值的绑定关系. 当创建一个对象的时候,会产生名称空间,存储对象中的名称和值的绑定关系.
类还有一个作用就是作为对象的模板, 所有属于同一个类的对象,都具备类的共同属性.
即使我们什么都不写,类中也会存在一些自带的属性,是从父类中继承的.
三、初始化函数
初始化函数应该与类是一个整体,应该将函数放入类中。 通常对象一旦创建就应该进行初始化,创建与初始化进行绑定。
初始化要用到init方法,该方法是对象产生之后才会执行,只用来为对象进行初始化操作。
class Person: # 初始化函数名称是固定的,该函数会在调用类时自动执行 # self形参必须有,但会自动获取,无需实参。self名称可自定义,但不建议修改,毕竟约定俗成。 def __init__(self,name,age): print("执行了__init__") print(self) # self就是要进行初始化的对象,系统会自动传值 self.name = name self.age = age?p1 = Person("alex",33) #从类Person中获取一个名叫p1的对象,对应的参数是"alex",33print(p1.__dict__) #结果是一个字典?输出结果:执行了__init__<__main__.Person object at 0x000001DD789E9400> #类Person下一个对象的内存地址{‘name‘: ‘alex‘, ‘age‘: 33} ??__init__方法强调: 1、该方法内可以有任意的python代码 2、一定不能有返回值
四、绑定方法
方法的定义:为了方便理解把函数称之为方法。
绑定方法:绑定方法是把对象与函数进行绑定。调用函数就变成了调用函数的方法。绑定方法就是将数据与处理数据的函数绑定在一起。
绑定方法分为两种,一种是绑定给对象的,一种是绑定给类的。
默认是绑定给对象的。
class Student: #建立一个Student的类 school = "BeiJing" #类的共同属性是学校名叫BeiJing? def __init__(self,name,sex,age): # 初始化函数,注意参数与定义的方法。 self.name = name self.sex = sex self.age = age? def sayHi(self): #与函数的初始化同级 print("hello my name is %s my age %s my sex %s" %(self.name,self.age,self.sex)) # 默认情况下,在类中定义的函数都是绑定方法,共同点是都会将对象作为第一个参数self。即对象必定要有,并以参数身份传入函数中。??stu1 = Student("egon","male",22)?# 当用对象来调用类中的方法时,默认把对象传入方法中# 用类名来调用时,则需要手动传入对象stu1.sayHi()Student.sayHi(stu1)?输出结果:hello my name is egon my age 22 my sex malehello my name is egon my age 22 my sex male?print(stu1.sayHi)# 这是一个绑定方法,本质上是Student类中的sayHi函数绑定给了地址为。。。的对象# 只要拿到对象,就同时拿到了数据和处理数据的方法输出结果:<bound method Student.sayHi of <__main__.Student object at 0x000002471E089B38>>
绑定给类的方法:
使用一个装饰器classmethod,必须有一个参数cls用来表示当前类,参数名可以自定义,但不建议修改(约定俗成,没有理由)。
class Student: school = "BeiJing"? def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age? @classmethod def print_school_name(self): print("学校名称为:%s" %Student.school)? @classmethod # 将此函数绑定给类,参数为cls def print_school(cls): print(cls.school)?stu1 = Student("kevin","male",11)stu1.print_school() # 调用的是加了装饰器的函数Student.print_school() # 没有传参,直接调用函数输出结果为:BeiJing?Student.print_school_name()stu1.print_school_name()输出结果为:学校名称为:BeiJing学校名称为:BeiJing
当要处理的数据包含在类中时,就应该绑定给类。 当要处理的数据包含在对象中时,就应该绑定给对象。
总结:
对象绑定方法,可以使用对象来调用,也可以使用类名来调用
在对象调用时会自动传入对象自己,类调用时不会自动传参
类的绑定方法,对象和类都能调用,并且都会自动传入这个类
类的绑定方法和对象的绑定方法的异同点相同点: 1.都会自动传值 2.都可以被类和对象调用不同点: 1.对象绑定方法在对象调用时,传的是对象自己,而类绑定方法自动传的是类自己. 2.第一个参数 一个cls 一个是self
五、非绑定方法
非绑定方法:即在类中的函数,既不绑定给类,也不绑定给对象。 特点:没有自动传参的效果,类和对象都能调用,就是一个普通函数。 应用场景:当你的这个功能既不需要访问类的数据,也不需要访问对象的数据,就可以作为一个非绑定方法。
class Teacher:? def __init__(self,name,sex): self.name = name self.sex = sex # @staticmethod 用于定义一个非绑定方法 @staticmethod def test_func(num): print("run %s" %num)?Teacher.test_func(1)输出结果:run 1
六、数据存取练习
import json?class Student:? school = "beijing"? def __init__(self,name,sex,age,classes): #初始化 self.name = name self.age = age self.sex = sex self.classes = classes?? def save(self): # 默认绑定给对象的函数 dic = {"name":self.name,"sex":self.sex, "age":self.age,"classes":self.classes} # 需要自己去创建字典 with open(self.name,"wt",encoding="utf-8") as f: # 文件名就是学生名 json.dump(dic,f) # 序列化数据? @classmethod # 类函数 def get_obj(cls,name): # 传入名字,调取储存的数据 with open(name,"rt",encoding="utf-8") as f: dic = json.load(f) obj = cls(dic["name"],dic["sex"],dic["age"],dic["classes"]) return obj??stu1 = Student("阿尔法","man",20,"py5期")stu2 = Student("张三","woman",20,"py5期")?stu1.save()stu2.save()??stu = Student.get_obj("阿尔法")print(stu)print(stu.__dict__)print(stu.name)输出结果为:<__main__.Student object at 0x000001CC57B10940>{‘name‘: ‘阿尔法‘, ‘age‘: 20, ‘sex‘: ‘man‘, ‘classes‘: ‘py5期‘}阿尔法
原文地址:https://www.cnblogs.com/realadmin/p/10116521.html