菜鸟学Python第二十一天

面向对象编程

  • 两种编程思想

    • 面向过程:解决问题的步骤,先干什么后干什么,按照步骤一步一步就解决问题.基于该编程思想就好比是在编写一条流水线,是一种机械式的思维方式.

      1. 优势:复杂问题流程化,进而简单化

      2. 劣势:可拓展性差,维护性差. (实现流程是固定的,一旦中间某一个步骤发生变化,将导致整体都需要修改)

      3. 使用场景:对拓展性要求低的软件,比如系统内核,脚本等. 但是对于拓展性强的的程序就不再适合该思想编程,即产生了面向对象编程.

    • 面向对象(OOP : object oriented programming ):对象指的是特征和技能的结合体(基于其特征能找到实际物体).基于该思想编写程序就好比在创造一个世界,你就是这个世界的上帝,是一种上帝的思维方式.

      1. 优势:

        1. 不用考虑繁琐的实现步骤 , 从一个流水线思维变成了上帝思维

        2. 可拓展性高(当需要一个新功能时,写一个具备新功能的对象,命令它去完成任务,各个对象出现问题,不会对其他对象产生影响,可维护性高)

      2. 劣势 :

        1. 编程的复杂度高于面向过程.

        2. 无法准确预知结果

      3. 应用场景: 需要较高的拓展性时,(直接与用户发生交互的程序例如:微信. qq等).......对于不需要拓展的程序而言,使用面向对象就会增加其复杂度.

  • 为什么要使用面向对象

    • 在当前市场情况下,百分之九十以上的得程序都需要直接与用户交互,而用户的需求千变万化,所以对编程的拓展性要求很高,故我们必须要使用面向对象编程.

  • 类与对象

    • 对象: 对象是特征与技能的结合体(基于其特征能找到实际对应对象)

    • 类:类是一个抽象的概念,是一系列具有相同某一技能或特征的的结合体.

    • 现有对象还是先有类:

      • 在现实生活中,一定是先有对象,后来随着人类文明的发展总结的类,对象是具体存在的,而类只是一种抽象的概念

      • 在程序中,务必先定义类,后调用类来产生对象.

        在程序中特征变量标识,技能函数标识

        因而类中最常见的无非是:变量和函数的定义

class Student:  # 定义类(类名首字母大写)
    school = 'Tsinghua'  # 相同特征,变量
    
    def learning():  # 相同技能,函数
        print('learning')
    
stu1 = Student()  # 调用类产生对象
print(obj)
​
# 运行结果
#  <__main__.Student object at 0x0000000002648358>
# 解释以上结果:模块名为main,其中Student类下有一个指定内存地址为xxx的对象
print(stu.school)  # 输出对象的属性(特征)
stu.learning()  # 输出对象的属性(技能)

注意:1.类中可以有任意python代码,这些代码在定义类的时候便会执行

2.因而会产生新的名称空间,用来存放类的变量名和函数名,可以通过"类名.__ dict__"查看

3.对于经典类来说 ,我们可以通过过字典操作类名称空间的名字,但是python为我们提供了专门的语法.

4.点是访问属性的语法,类中定义的名字,都是类的属性

# 程序中类的用法
#  访问
1,类名.变量名  # 相当于经典操作"类名.__ dict__['变量名']
2,类名.函数名()  #  相当于经典类操作"类名.__ dict__['函数名']
# 增加
类名.变量名 = 变量值 # Student.classes = '计算机一班'
# 修改
类名.变量名 = 变量值 # 即如同字典的操作,更改已存在的变量(key=新value)
# 删除
del 类名.函数名
​
​
# 对象的初始化__init__:该方法是在对象产生后才会执行,只用来为对象进行初始化操作,可以有任意代码,但是一定不能有返回值
class Student:
    ......
    # 函数的初始化(self一定要有,表示要初始化的对象)
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    ......
    
    
s1 = Student('jason', 23, 'male') # 相当于先调用类产生空对象s1,然后调用类.__init__(s1,'jason',23,'male')
# 对象的操作,类似于类的操作
# 对象名.变量名.......

属性查找与绑定方法

  • 属性查找

    类有两种属性:数据属性和函数属性

    1. 类的数据(变量)属性是所有对象共享的

    2. 类的函数属性是绑定给对象用的(obj,method称为绑定方法,内存地址都不一样)

s1 = Student()
s2 = Student()
​
print(id(Student.school)) # 通过类名.变量名访问类中数据
print(id(s1.school))  # 通过对象名访问变量
print(id(s2.school))
​
输出结果
'''
4377347328
4377347328
4377347328
4377347328
'''
得出结论:类的数据是共享的,id都一致
    
 
print(id(Student.learning)) # 通过类名.函数名访问类中数据
print(id(s1.learn))  # 通过对象名访问函数
print(id(s2.learn))
​
输出结果:
 '''
<function OldboyStudent.learn at 0x1021329d8>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>>
'''
  • 类中属性查找的顺序:obj.name会先从自己的名称空间里找name,找不到则去类中找(类中找不到就去父类中找...最后没找到就会报错).

  • 绑定方法
  • 绑定方法:就是将对象或者类与函数进行绑定的方法,这里的方法指的也就是函数

    对象本质上就是一种存放数据的容器 函数是用于处理数据的代码 绑定方法就是将数据与处理数据的函数绑定在一起

  • 为什么要进行绑定:当没有进行绑定时

    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))
      ​
          # 默认情况下 在类中定义的函数都是绑定方法,共同点是,都会将对象作为第一个参数self
          
      ​
      stu1 = Student("一个学生","man",18)
      ​
      stu1.sayHI()  # 当用用对象来调用类中的方法时,默认把对象传入方法中
      ​
      Student.sayHI(stu1)  # 而用类名来调用时,则需要手动传入对象
      ​
      ​

      类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法

      强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法init也是一样的道理)

 

  • 绑定给类的方法

    • 绑定的方法包括两种,常用的是绑定给对象的,另一种是绑定给类的

    class Student:
        school = "Tsinghua"def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    ​
        # 绑定给类的方法 使用一个装饰器叫classmethod,必须有一个参数,表示当前类,参数名也可以自己定义,建议不要修改
        @classmethod
        def print_school(cls):  # 输出类里面叫school的属性
            print(cls.school)
    ​
        # def print_school2(self):  # 输出类里面叫school的属性
        #     print(self.school)
    # 这是绑定给对象的方法
        def sayHello(self):
            print(self.name, " 说: 你好")
    ​
    ​
    ​
    # Student.print_school_name()
    ​
    Student.print_school()
    • 一个方法到底应该绑定给对象还是帮对给类? 当要处理的数据包含在类中时,就应该绑定给类 当要处理的数据包含在对象中时,就应该绑定给对象

    • 绑定给对象和绑定给类的差别

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

      • 类调用时不会自动传参

        类的绑定方法,对象和类都能调用,并且都会自动传入这个类

  • 非绑定方法(了解)

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)
​
​
#  什么是非绑定方法 再类中 即不绑定给类 也不绑定给对象
#  特点:没有自动传参数的效果 ,类和对象向都能调用,就是一个普通函数
#  当你的这个功能不需要访问类的数据 也不需要访问对象的数据,就可以作为一个非绑定方法
#  使用场景较少
 

猜你喜欢

转载自www.cnblogs.com/liusijun113/p/10116467.html