python-类和对象

文章目录

      • 一、类和对象
      • 二、属性的访问顺序
      • 三、初始化函数
      • 四、绑定方法
      • 五、为什么要绑定
      • 六、绑定给类的方法
      • 七、非绑定方法

一、类和对象

  1. 什么是面向对象:

    在介绍面向对象之前,要先明确面向过程

    面向过程: 解决问题的步骤、流程,即第一步干什么,第二步干什么,其目的是将一个复杂的问题,拆分为若干的小的问题,按照步骤一一解决,也可以说将一个复杂的问题流程化为其制定一个固定的实现流程,从而变得简单化。

    面向过程编程优缺点:

    优点:复杂的问题简单化

    缺点:由于其实现流程是固定的,一旦中间某一个步骤发生了修改,导致整体都需要修改

    面向对象:是一种编程思想,即编写代码的方式方法,是Object oriented Programing的简称,就是面向对象的英文缩写将程序看做是一堆对象的集合,实现功能的方式就是对象之间交互来实现

    面向对象编程优缺点:

    优点:

  2. 不用考虑繁琐的实现步骤,从一个操作工,变成了老板

  3. 扩展性高了,当需要一个新功能时,搞一个具备新功能的对象,命令它去完成任务

  4. 各个对象之间的耦合度低,当一个一个对象出现了问题,不会对其他对象产生影响

  5. 可维护性高

    缺点:

  6. 面向对象的复杂度比面向过程高

  7. 无法预知执行结果,就像lol的游戏过程,一定不能把过程写死,每个英雄的行为是不固定的

    使用场景:

    需要较高的扩展性时(直接与用户发生交互的程序例如,qq微信)对于不需要扩展的程序而言,使用面向对象反而增加了复杂度

  8. 什么是对象:具备某些特征与技能的结合体,是实实在在存在的具体物体

  9. 什么是类:类是一个抽象概念,不是实际存在的,是根据一些具备相同特征和技能的对象抽取得到的,比如说人类

  10. 类与对象之间的关系:类包含了一系列相同特征和技能的对象, 对象是属于某个类的实例

  11. 先有类还是先有对象:在生活中是先有对象再根据对象的特征和技能得到一个类型,在程序中先有类,才能通过类来产生对象,要先确定对象具备什么特征和什么行为才能产生对象

  12. 为什么要使用面向对象:很多的程序与用户直接打交道,而用户的需求千变万化,所以对扩展性要求非常高,面向对象编程的本质就是使用不同的对象来完成程序

#在类中描述对象的特征和行为
class Person:
    # 用变量来描述特征
    name = "李四"
    sex = "man"
    age = 20

#得到对象,通过调用类,也称之为实例化或创建对象
obj = Person()
print(obj)
#使用对象的属性
print(obj.name)
print(obj.age)
print(obj.sex)
class Student:
    number = "007"
    name = "盖伦"
    sex = "man"
    age = 18

    # 学生的学校由于每个学生的学校都是相同所以将其放到类中
    school = "Tsinghua"

#创建了两个学生对象
stu1 = Student()
stu2 = Student()

#每个对象内存地址都是不同的,在创建对象时,计算机会申请一个新的内存空间,并将对象中的内容存进去
print(stu1) #<__main__.Student object at 0x000001A2B2EC7F28>
print(stu2) #<__main__.Student object at 0x000001A2B2EC7F60>

#由于name的值时声明在类中的,所以每个对象使用的都是同一份
print(id(stu1.name)) #1798298182032
print(id(stu2.name)) #1798298182032

#为对象单独定制属性
#stu1.name = "韩信"
#stu2.name = "陈大炮"

print(stu1.name)
print(stu1.name)

#通过__dict__可以获取一个对象中包含的内容
stu1.age = 30
stu1.name = "韩信"
stu2.name = "陈大炮"
print(stu1.__dict__) #{'age': 30, 'name': '韩信'}
print(stu2.__dict__) #{'name': '陈大炮'}

#获取类中包含的内容
print(Student.__dict__)

二、属性的访问顺序

class Car:
    c_type = "保时捷"
    color = "red"
    price = 400000


c1 = Car()
c2 = Car()

#当对象中不存在是会到类中去找
print(c1.__dict__) #{}
print(c2.__dict__) #{}
print(c1.c_type) #保时捷

c1.c_type = "法拉利"
print(c1.__dict__) #{'c_type': '法拉利'}
print(c2.__dict__) #{}
print(c1.c_type) #法拉利
print(c2.c_type) #保时捷

总结:

  1. 查找顺序为:对象==>类

  2. 当创建一个类的时候,会产生名称空间,存储类中名称和值的绑定关系

  3. 当创建一个对象的时候,会产生名称空间,存储对象中名称和值的绑定关系

  4. 类还有另一个作用就是作为对象的模板,所有属于同一个类的对象,都具备类中的公共内容

  5. 即使我们什么都不写 类中也存在一些自带的属性,是从父类得到的

    class A:
        pass
    
    print(A.__dict__)
    

三、初始化函数

class Student:
    # 定义一个函数 用于为对象设置属性
    def set_attr(obj, name, sex, age):
        obj.name = name
        obj.sex = sex
        obj.age = age

stu1 = Student()
#指定属性
stu1.name = "张无忌"
stu1.sex = "man"
stu1.age = 18

stu2 =Student()
stu2.name = "周芷若"
stu2.sex = "woman"
stu2.age = 78

print(stu2.name) #周芷若


stu3 = Student()
Student.set_attr(stu3,"金毛狮王","man",80)
print(stu3.__dict__)  #{'name': '金毛狮王', 'sex': 'man', 'age': 80}
class Person:
    #初始化函数名称是固定,该函数会在调用类是时自动执行,self参数必须有,表示要进行初始化的对象,系统会自动传值
    def __init__(self,name,age):
        print("执行了 __init__")
        print(self)
        self.name = name
        self.age = age

p1 = Person("张三丰",80)

print(p1.__dict__)

p2 = Person("李狗蛋",20)
print(p2.__dict__)
# init 函数用于初始化对象,它会在创建对象时自动执行,并传入调用类时传递的参数,第一个参数表示要初始化的对象本身
# self(第一个)参数不需要手动传递
# self表示对象自己,是一个形式参数,名字可以随便取,但是不建议修改

四、绑定方法

  1. 什么是绑定:把两个东西捆绑在一起

  2. 什么是方法:方法就是函数,函数是专业术语,不好理解,面向对象编程思想是要我们模仿现实生活中的抽象概念,为了方便理解就把函数称之为方法

  3. 绑定方法:就是把对象与函数进行绑定

    如何使用绑定方法:

    class Student:
        school = "BeiJing"
    
        def __init__(self,name,sex,age):
            self.name = name
            self.sex = sex
            self.age = age
    
        def learning(self):
            print("正在学习..")
    
        def sayHI(self):
            print("hello my name is %s my age:%s my sex:%s" % (self.name,self.age,self.sex))
    
    # 当用用对象来调用类中的方法时,默认把对象传入方法中
    # 而用类名来调用时,则需要手动传入对象
    stu1 = Student("张三","man",18)
    stu1.sayHI() #hello my name is 张三 my age:18 my sex:man
    Student.sayHI(stu1) #hello my name is 张三 my age:18 my sex:man
    print(stu1.sayHI) #> 这是一个绑定方法,本质上是Student类中的sayHI函数,现在把这个函数绑定给了地址为0x000001784F889C50的对象
    

五、为什么要绑定

name = "张三"
age = 20
sex = "男"

name1 = "李四"
age1 = 25
sex1 = "男"

name2 = "赵六"
age2 = 30
sex2 = "男"

def show_info(name,age,sex):
    print("hello i am %s my age:%s my sex:%s" % (name,age,sex))
    
show_info(name,sex,age)
show_info(name1,sex1,age1)
show_info(name2,sex2,age2)
# 第一个问题:传递参数,必须手动传递,很有可能传参顺序而发生错误
# 第二个问题:每次处理数据都需要手动传参数
# 第三个问题:当要处理的数据特别的多,就不能再定义为变量了你可以使用列表出来存储要处理的数据
# 但是每次处理都需要先获取数据,在传递给处理数据的函数
# 所以将要处理的数据与处理数据的函数进行绑定

六、绑定给类的方法

class Student:
    school = "beijing"

    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    #绑定给类的方法
    @classmethod
    def print_school(cls):  
        #输出类里面叫school的属性
        print(cls.school)
        
	#这是绑定给对象的方法
    def sayHello(self):
        print(self.name, "说你好")

#类的绑定方法,对象和类都能调用,并且都会自动传入这个类
Student.print_school() #beijing

stu1 = Student("张三", "woman", 20)
stu1.print_school() #beijing

#对象绑定方法可以使用对象来调用,也可以使用类名来调用
#在对象调用时会自动传入对象自己
#类调用时不会自动传参

练习 :

#有一个Dog类,每一个Dog对象都应该会叫、会跑请用面向对象来完成
class Dog:
    def __init__(self,nikename,gender,age):
        self.nikename = nikename
        self.gender = gender
        self.age = age

    def run(self):
        print("不好了 ",self.nikename,"跑了 ")

    def bark(self):
        print("听",self.nikename,"在瞎叫...")

d1 = Dog("金毛","母的",2)
d2 = Dog("大黄","公的",3)

d1.run()
d2.bark()

七、非绑定方法

  1. 什么是非绑定方法:在类中即不绑定给类也不绑定给对象

    特点:没有自动传参数的效果,类和对象向都能调用,就是一个普通函数,当你的这个功能不需要访问类的数据也不需要访问对象的数据,就可以作为一个非绑定方法,使用场景较少

class Teacher:

    def __init__(self,name,sex):
        self.name = name
        self.sex = sex

    # @staticmethod 用于定义个非绑定方法
    @staticmethod
    def test_func(num):
        print("test_func run!")
        print(num)


#可以使用类名调用
Teacher.test_func(1) 

t1 = Teacher("张三","男")
t1.test_func(100)
print(t1.test_func)

练习:

1.创建Student类

2.拥有以下属性: 姓名 性别 年龄 学校 班级

3.拥有以下方法

save(name) 其作用是将这个对象序列化到文件中

get_obj(name)	其作用是根据name从文件中反序列化为得到一个对象

分析save方法和get_obj 应该作为绑定给对象还是绑定给类

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("张三","woman",20,"py5期")
stu2 = Student("李四","man",20,"py5期")

stu1.save()
stu2.save()

stu = Student.get_obj("张三")
print(stu)
print(stu.name)

你可能感兴趣的:(Python学习)