python笔记9-面向对象编程

面向对象编程

1.面向对象简介

❤️Python支持面向过程、面向对象、函数式编程等多种编程范
式。

  1. 面向对象和面向过程总结
    1. 都是解决问题的思维方式,都是代码组织的方式。
    2. 面向过程是一种“执行者思维",解决简单问题可以使用面向过程
    3. 面向对象是一种“设计者思维”,解决复杂、需要协作的问题可以使用面向对象
  2. 面向对象离不开面向过程:
    1. 宏观上:通过面向对象进行整体设计
    2. 微观上:执行和处理数据,仍然是面向过程

2.对象的进化

随着编程面临的问题越来越复杂,编程语言本身也在进化,从主要
处理简单数据开始,随着数据变多进化“数组”; 数据类型变复杂,
进化出了“结构体”; 处理数据的方式和逻辑变复杂,进化出了“对
象”。

3.类的定义

  1. 类:我们叫做 class
  2. 对象:我们叫做 object , instance (实例)。以后我们说某个类的对象,某个类的实例。是一样的意思。
  3. 类和对象的关系比喻:我们把对象比作一个“饼干”,类就是制造这个饼干的“模具”。

4.属性和方法

  1. 简介
    我们通过类定义数据类型的属性(数据、状态)和方法(行为),也就是
    说,“类将行为和状态打包在一起”。
    从一个类创建对象时,每个对象会共享这个类的行为(类中定义的方法),但会有自己的属性值(不共享状态)。更具体一点:“方法代码是共享的,属性数据不共享”。
    在这里插入图片描述

5.类对象

❤️Python中,“一切皆对象”。类也称为“类对象”,类的实例也
称为“实例对象”。

  1. 语法
    class 类名:
    	类体
    
    要点:
    1. 类名必须符合“标识符”的规则;一般规定,首字母大写,多个单词使用“驼峰原则”。
    2. 类体中我们可以定义属性和方法
    3. 属性用来描述数据,方法(即函数)用来描述这些数据相关的操作
  2. 类对象举例
    class Student:
    	def __init__(self, name, score):  # 构造方法第一个参数必须为self
    		self.name = name  # 实例属性
    		self.score = score  # 实例属性
    	def say_score(self):  # 实例方法
    		print("{0}的分数是{1}".format(self.name, self.score))
    s1 = Student('zhangsan', 80)  # s1是实例对象,自动调用__init__()方法
    s1.say_score()
    
  3. 类对象内存结构图
    在这里插入图片描述

4.__init__()构造方法和__new__()方法

初始化对象,我们需要定义构造函数 __init__() 方法。构造方法用于执行“实例对象的初始化工作”,即对象创建后,初始化当前对象的相关属性,无返回值。
解释:相当于我们想要建一座房子,计划为这座房子买家具,瓷砖来装修。这里的家具,瓷砖要装修的就是__init__()构造方法;这里的建的房子就是__new__()方法。我们先建房子在装修,相当于我们先调用__new__()方法来创建对象,接着用__init__()构造方法初始化对象。

  1. __init__()要点:
    1. 名称是固定的。必须为:__init__()
    2. 第一个参数是固定的。必须为:selfself指的就是刚刚创建好的实例对象。
    3. __init__()构造方法通常是用来初始化实例对象的实例属性的。如下代码就是初始化实例属性:namescore
      def __init__(self,name,score):
      	self.name = name         #实例属性
      	self.score = score
      
    4. 通过类名(参数列表)来调用构造函数。调用后,将创建好的对象返回给相应的变量。比如:s1=Student('zhangsan',80)
    5. __init__()方法:初始化创建好的对象,初始化指的是:“给实例属性赋值”。
    6. __new__()方法:用于创建对象,我们一般不需要重新定义该方法。
    7. 如果我们不定义 __init__() 方法,系统会提供一个默认的 __init__() 方法。如果我们定义了带参的 __init__() 方法,系统不创建默认的 __init__() 方法。

5.实例属性和实例方法,对象的其它操作

  1. 实例属性
    在这里插入图片描述

    1. 实例属性是从属于实例对象的属性,也称为“实例变量”。他的使用有如下几个要点:
      1. 实例属性一般在 __init__() 方法中通过如下代码定义:self.实例属性名 = 初始值
      2. 在本类的其他实例方法中,也是通过 self 进行访问:self.实例属性名
      3. 创建实例对象后,通过实例对象访问:
        obj01 = 类名() # 创建和初始化对象,调用 __init__() 初始化属性
        obj01.实例属性名 = 值 # 可以给已有属性赋值,也可以新加属性
    2. 实例代码
      class Student:
          def __init__(self,name,score):
              self.name = name #增加name属性
              self.score = score #增加score属性
          def say_score(self):
              self.age = 18     #增加age属性
              print("{0}的分数是{1}".format(self.name,self.score))
      s1 = Student("张三",80)
      s1.say_score()
      print(s1.age)
      s1.salary = 3000 #s1对象增加salary属性
      s2 = Student("李四",90)
      s2.say_score()
      print(s2.age)
      
  2. 实例方法
    实例方法是从属于实例对象的方法。

    1. 语法
      def  方法名(self [, 形参列表]):
      	函数体
      
    2. 方法的调用格式如下:对象.方法名([实参列表]
    3. 要点:
      1. 定义实例方法时,第一个参数必须为 self 。和前面一样, self 指当前的实例对象。
      2. 调用实例方法时,不需要也不能给 self 传参。 self 由解释器自动传参
        1. 实例对象的方法调用本质
          在这里插入图片描述
      3. 函数和方法的区别
        1. 都是用来完成一个功能的语句块,本质一样。
        2. 方法调用时,通过对象来调用。方法从属于特定实例对象,普通函数没有这个特点
        3. 直观上看,方法定义时需要传递self,函数不需要
  3. 对象的其它操作

    1. dir(obj) 可以获得对象的所有属性、方法
    2. obj.__dict__ 对象的属性字典
    3. pass 空语句
    4. isinstance(对象,类型) 判断“对象”是不是“指定类型”

6.类对象、类属性、类方法、静态方法

  1. 类对象
    我们在前面讲的类定义格式中, class 类名: 实际上,当解释器执行class 语句时,就会创建一个类对象。
  2. 类属性
    1. 简介:
      类属性是从属于“类对象”的属性,也称为“类变量”。由于,类属性从属于类对象,可以被所有实例对象共享。
    2. 语法:
      class 类名:
      	类变量名 = 初始值
      
  3. 类方法
    1. 简介:
      类方法是从属于“类对象”的方法。类方法通过装饰器 @classmethod 定义。
    2. 语法:
      @classmethod
      def 类方法名(cls [,形参列表]) :
      	方法体
      
    3. 注意:
      1. @classmethod 必须位于方法上面一行
      2. 第一个 cls 必须有; cls 指的就是“类对象”本身
      3. 调用类方法格式: 类名.类方法名(参数列表) 。 参数列表中,不需要也不能给 cls 传值
      4. 类方法中访问实例属性和实例方法会导致错误
      5. 子类继承父类方法时,传入 cls 是子类对象,而非父类对象
  4. 静态方法
    1. 简介:
      Python中允许定义与“类对象”无关的方法,称为“静态方法”。“静态方法”和在模块中定义普通函数没有区别,只不过“静态方法”放到了“类的名字空间里面”,需要通过“类调用”。静态方法通过装饰器@staticmethod来定义。
    2. 语法:
      @staticmethod
      def 静态方法名([形参列表]) :
      	方法体
      
    3. 注意
      1. @staticmethod 必须位于方法上面一行
      2. 调用静态方法格式: 类名.静态方法名(参数列表)
      3. 静态方法中访问实例属性和实例方法会导致错误

7.__del__方法 (析构函数)和垃圾回收机制

  1. 简介
    __del__() 称为“析构方法”,用于实现对象被销毁时所需的操作。比如:释放对象占用的资源,例如:打开的文件资源、网络连接等。Python实现自动的垃圾回收,当对象没有被引用时(引用计数为0),由垃圾回收器调用 __del__() 。我们也可以通过 del语句 删除对象,从而保证调用 __del__() 。系统会自动提供 __del__方法 ,一般不需要自定义析构方法。
  2. 代码示例
    #析构函数
    class Person:
        def __del__(self):
            print("销毁对象:{0}".format(self))
    p1 = Person()
    p2 = Person()
    del p2  # 先删除对象p2-->执行print("程序结束")-->引用对象由1变为0-->删除p1
    print("程序结束")
    # 运行结果
    销毁对象:<__main__.Person object at
    0x02175610>
    程序结束
    销毁对象:<__main__.Person object at
    0x021755D0>
    

8.__call__ 方法和可调用对象

  1. Python 中,凡是可以将 () 直接应用到自身并执行,都称为可调用对象。
  2. 可调用对象包括自定义的函数、Python 内置函数、以及本笔记所说的实例对象。
  3. 定义了 __call__() 的对象,称为“可调用对象”,即该对象可以像函数一样被调用。
  4. 该方法使得实例对象可以像调用普通函数那样,以“对象名()”的形式使用。
  5. 代码示例:
    def f1():
        print("f1")
    f1()   #本质也是调用了__call__()方法
    class Car:
        def __call__(self, age,money):
            print("__call__方法")
            print("车龄:{0},金额:{1}".format(age,money))
    f2 = Car()
    f2(3,200000)    #像调用函数那样调用,本质也是调用了__call__()
    # 运行结果
    f1
    __call__方法
    车龄:3,金额:200000
    

9. 方法没有重载

  1. 简介:
    如果我们在类体中定义了多个重名的方法,只有最后一个方法有效。

10.方法的动态性

  1. 简介:
    Python是动态语言,我们可以动态的为类添加新的方法,或者动态的修改类的已有的方法
  2. 代码示例:
    #测试方法的动态性
    class Person:
        def work(self):
            print("天天向上!")
    def play_game(self):
    print("玩游戏")
    def work2(s):
        print("好好学习,天天向上!")
    Person.play = play_game
    Person.work = work2
    p = Person()
    p.play()
    p.work()
    
    我们可以看到, Person 动态的新增了 play_game 方法,以及用 work2替换了 work 方法

11.私有属性和私有方法(实现封装)

  1. Python对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。关于私有属性和私有方法,有如下要点:
    1. 通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。
    2. 类内部可以访问私有属性(方法)
    3. 类外部不能直接访问私有属性(方法)
    4. 类外部可以通过 _类名__私有属性(方法)名 ”访问私有属性(方法)
  2. 注意:
    ⚠️【注】方法本质上也是属性!只不过是可以通过()执行而已。所以,此处讲的私有属性和公有属性,也同时讲解了私有方法和公有方法的用法。

12.@property 装饰器

  1. 简介:
    1. @property可以将一个方法的调用方式变成属性的调用方式。
    2. 既要保护类的封装特性,又要让开发者可以使用“对象.属性”的方式操作操作类属性,除了使用 property() 函数,Python 还提供了 @property 装饰器。通过 @property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对“()”小括号。
  2. 语法
    @property
    def方法名(self):
    	代码块
    
  3. 代码示例:
    1. 例如,定义一个矩形类,并定义用@property 修饰的方法操作类中的 price 私有属性,代码如下:
    class Car:
    	def __init__(self, price):
    		self.__price = price
    		
    	@property  # 相当于price属性的getter方法
    	def price(self):
    		return self.__price
    car_p = Car(600000)
    #直接通过方法名来访问 price 方法
    print("汽车的价格是:",car_p.price)
    # 运行结果
    汽车的价格是:600000
    
    1. 上面程序中,使用 @property 修饰了 price() 方法,这样就使得该方法变成了 price 属性的 getter 方法。需要注意的是,如果类中只包含该方法,那么 price 属性将是一个只读属性。
      也就是说,在使用 Car 类时,无法对 price 属性重新赋值,即运行如下代码会报错:
    car_p = 800000
    print("修改后的价格:",car_p.price)
    # 运行结果
    Traceback (most recent call last):
    File "C:\Users\mengma\Desktop\1.py", line 10, in <module>
    car_p.price = 800000
    AttributeError: can't set attribute
    

13.setter装饰器

  1. 接目录12而要想实现修改 price 属性的值,还需要为 price 属性添加setter 方法,就需要用到 setter 装饰器
  2. 语法:
    @方法名.setter
    def 方法名(self, value):
    	代码块
    
  3. 代码示例:
    1. 例如,为 Car 类中的 price 方法添加 setter 方法,代码如下:
    class Car:
    	def __init__(self, price):
    		self.__price = price
    		
    	@property  # 相当于price属性的getter方法
    	def price(self):
    		return self.__price
    
    	@price.setter  # 相当于price属性的setter方法
    	def price(self, value):
        	self.__price = value
    car_p = Car(600000)
    car_p = 800000
    print("修改后的价格:",car_p.price)
    # 运行结果
    修改后的价格:800000
    
    这样,price 属性就有了 gettersetter 方法,该属性就变成了具有读写功能的属性。

14.deleter装饰器

  1. 简介:
    除上述12、13之外,还可以使用 deleter 装饰器来删除指定属性
  2. 语法:
    @方法名.deleter
    def 方法名(self):
    	代码块
    
  3. 示例代码:
    class Car:
    	def __init__(self, price):
    		self.__price = price
    		
    	@property  # 相当于price属性的getter方法
    	def price(self):
    		return self.__price
    
    	@price.setter  # 相当于price属性的setter方法
    	def price(self, value):
        	self.__price = value
    
        @price.deleter
    	def price(self):
    		self.__price = 0
    car_p = Car(600000)
    del car_p.price
    print("删除后的price值为:",car_p.price)
    # 运行结果
    删除后的price值为:0
    
  4. 总结
    1. @property装饰器负责获取返回值,起读的作用。
    2. @方法名.setter装饰器负责设置、处理、限制@property获取的返回值,起写的作用。
    3. @方法名.deleter装饰器负责属性的删除,起删的作用。

16.属性和方法命名总结

  1. _xxx :保护成员,不能用 from module import * 导入,只有类对象和子类对象能访问这些成员。
  2. __xxx__ :系统定义的特殊成员
  3. __xxx : 类中的私有成员,只有类对象自己能访问,子类对象也不能访问。(但,在类外部可以通过 对象名. _类名__xxx 这种特殊方式访问Python不存在严格意义的私有成员)
    ⚠️再次强调,方法和属性都遵循上面的规则。

17.类编码风格

  1. 类名首字母大写,多个单词之间采用驼峰原则。
  2. 实例名、模块名采用小写,多个单词之间采用下划线隔开
  3. 每个类,应紧跟“文档字符串”,说明这个类的作用
  4. 可以用空行组织代码,但不能滥用。在类中,使用一个空行隔开方法;模块中,使用两个空行隔开多个类

18.关于None和判断的总结

  1. None是什么?
    1. 与C和JAVA不同,python中是没有 NULL 的,取而代之的是 None
    2. None 是一个特殊的常量,表示变量没有指向任何对象。
    3. 在Python中, None 本身实际上也是对象,有自己的类型 NoneType
    4. 你可以将 None 赋值给任何变量,但我们不能创建 NoneType 类型的对象。
    5. ⚠️None不是FalseNone不是0,None不是空字符串。None
      和任何其他的数据类型比较永远返回False。
  2. None和其他类型的比较
    1. None和其他任何类型比较都会返回False
      a = None
      if a is None and a==None:
      	print("a是None")             #会执行
      if a==False or a==0:
      	print("None不等于False")       #不会被打印
      
    2. 空列表、空字符串、1、0之间的比较
      1. if语句判断时,空列表[]、空字典{}、空元组()0等一系列代表空和无的对象会被转换成False
        a=[];b=();c={};d="";e=0;f=None
        if (not a) and (not b) and (not c) and
        (not d) and (not e) and (not f):
            print("if判断时,空列表[]、空字符串、0、None等代表空和无的对象会被转换成False")
        
      2. ==is 判断时,空列表、空字符串、空字典不会自动转成False,是它们本来的类型。
        '''
        ==和is判断时,空列表、空字符串、空字典不会自动转成False
        '''
        a = []
        b = {}
        c = ()
        d = ''
        e = 0
        if (b == False or c == False or a == False or d == False):
            print('==判断时,空字典或空元组是False')  # 不会执行
        if (e == False):  # 1是True 0是False
            print('==时,0会转成False')  # ==时,0会转成False
        if (b is False or c is False or a is False or d is False):
            print('is判断时,空字典或空元组是False')  # 不会执行
        if (0 is False):  # 1是True 0是False
            print('is时,0会转成False')  # is时,0不会转成False
        
        
      3. 10在进行任何比较时,1会被转换成ture,0会被转换成false
        if 1:
        	print("1在比较时会被转换为ture")
        if not 0:
        	print("0在比较时会被转换为false")
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值