Python基础学习笔记(一)

一、下载Python

  1. 官网:https://www.python.org/

  2. 下载最新版本:python-3.10.2-amd64.exe

  3. 安装:

    1. Install Now:快速安装,勾选添加环境变量;
    2. Customize Installation:自定义安装,选择安装位置,勾选2、3、4选项;
  4. 学习使用:

    IDLE字体修改:Options > Configure IDLE 选择字体为 Consolas。

    IDLE两种模式:

    • 交互模式:直接在IDLE中输入指令,给出一个指令,机器立刻给出一个反馈。

      • 输入 print("Hello World!") 打印hello world;
      • 输入 算数自动计算出结果……
      • 输入 import this ,打印Python的禅宗(py的优点等等)。
    • 编辑器模式:以 .py 结尾的文件,包含全部代码。

      • 点击 File > New File 创建新文件,文件后缀为 .py 结尾;

      • 输入测试游戏代码,保存 ctrl + s ,点击 Run > Run Module 运行文件;

        """ 第一个小游戏 """
        
        temp = input("猜数字小游戏,猜猜我想的是哪个数字:")
        guess = int(temp)
        
        if guess == 8:
            print("你好棒棒")
            print("猜对了也没奖励!")
        else:
            print("猜错了!正确答案是8")
        
        print("游戏结束")
        

      注意

      ​ 遵守Python的语法规范,代码样式指导手册PEP8

      ​ 官网:https://www.python.org/dev/peps/pep-0008/

  5. BIF内置函数:

    在IDLE中输入:dir(__builtins__) 查看Python的所有内置函数,例如:print()、input() 等;

  6. 在 Python 中可以通过 help() 内置函数或者 __doc__ 属性查看某个函数的说明文档,如下代码所示:

    # 查看 print() 内置函数的说明文档
    help(print)
    print(print.__doc__)
    
  7. Python的注释:

    • 单行注释:使用 # 开头,例如:# 单行注释
    • 多行注释:使用三个连续的引号 ''' 或者 """ 作开头和结尾,也叫长字符串,不支持嵌套。
  8. 为自定义函数设置说明文档:

    当使用 help() 内置函数或者 __doc__ 属性即可查看的说明文档

    # 定义一个比较数字大小的函数
    def num_max(num1, num2):
        """
        比较两个数字的大小
        :param num1:形参1,数字1
        :param num2:形参2,数字2
        :return:大的数字,max_num = num1 if num1 > num2 else num2
        """
        max_num = num1 if num1 > num2 else num2
        return max_num
    
    help(num_max)
    print(num_max.__doc__)
    

二、变量

变量:关联一个对象的标识符。以字母(区分大小写)、数字、下划线组成,但不能以数字开头,支持中文。

  1. 格式一:变量名 = 变量值,例如:x = 3

  2. 格式二:变量名1, 变量名2 = 变量值1, 变量值2,例如:x, y = 3, 4

  3. 格式三:变量名1 = 变量名2 = 变量值,例如:x = y = 3

  4. 使用变量:例如:print(x) ,即可输出变量的值;

  5. 变量删除:del 语句:

    • 格式:del 变量名1,变量名2 ……
    • 作用:删除变量,接触与对象的关联
    • 自动化内存管理的引用计数:每个对象记录着被变量引用的次数,次数为 0 时自动销毁。
  6. 两个值互换:

    x = 3
    y = 5
    # 方式一
    z = x
    x = y
    y = z
    print(x, y)
    5 3		# 输出结果
    
    # 方式二,变量的格式二
    x, y = y, x
    print(x, y)
    5 3		# 输出结果
    

三、数据类型

  1. 核心数据类型:

    • 变量没有数据类型,但关联的对象有类型;
    • 使用 type 函数查看类型。
  2. 空对象:None

    作用

    • 占位
    • 接触与对象的绑定 关系
  3. 整形:int

  4. 浮点型:float

    • 小数:0.1

    • 科学计数法:e/E±指数,例如:1.23e-2 (等于0.0123) 、1.234e5 (等于123400.0)

  5. 字符串:str

  6. 复数(特定运算中涉及):complex

    • 由实部和虚部组成的数字;
    • 虚部以 jJ 结尾;
    • 字面值:1j、1+1j。
  7. 布尔:bool

  8. 类型转换:

    格式数据类型(变量值),例如:int(“50”)、str(100)等等。

四、运算符

  1. 算术运算符:+ 、- 、* 、/ (整除)、// (地板除,结果不含小数)、%、** (幂运算,次方)。
  2. 增强运算符:+=、-=、*=、/=等,与算术运算符个数一致。
  3. 比较运算符:< 、<= 、> 、>= 、== 、!= ,返回一个布尔值。
  4. 逻辑运算符:and、or、not
    • 短路运算:一旦结果确定,后面语句不执行,例如:1>2 and input(“请输入”) == “”
  5. 身份运算符:is、is not
  6. 优先级:(由上至下,算术 --> 身份)

五、语句

    1. 物理行:实际代码行数,一个物理行可包括多个逻辑行,使用分号分割;

    2. 逻辑行:对应一条指令,建议一个物理行对应一个逻辑行;

    3. 换行:

      • 隐式换行:使用括号,所有的括号中内容随意换行;

      • 显示换行:使用折行符 \ 换行,必须放在行的末尾;

  1. pass 语句:用于填充语法空白;

  2. 选择语句:

    • if elif else语句:注意缩进,冒号

      if 条件1:
          满足条件1时执行
      elif 条件2:
          满足条件2时执行
      else:
          都不满足时执行
      
    • 真值表达式:如果变量有值(不是None、“”、False),则为True。

    • 条件表达式 (三元表达式):根据条件,去为变量赋值,例如:x = 2 if 2 > 1 else 1。

  3. 循环语句:

    • while语句:

      while 条件:
          循环体
      #   break
      else:
          不满足条件
      
    • for语句:遍历可迭代元素

      for 变量名 in 可迭代对象:
          循环体
      else:
      
    • range函数:整数生成器,倒序时步长取负值

      • 接收三个参数,分别是:开始、结束、步长,含开始不含结尾。开始默认值 0,步长间隔默认值 1;
      • range(1, 5, 1),指生成1、2、3、4 的整数;
      • range(1, 5),参数代表开始、结束,步长间隔取默认值;
      • range(5),指生成0、1、2、3、4 的整数,其他参数取默认值;
  4. 跳转语句:只存在循环语句中

    • break语句:跳出循环
    • continue语句:跳出本轮循环

六、容器类型

  1. 通用操作:

    • 加法操作:使用加号将多个字符串拼接为一个字符串,字符串间可简写忽略加号;

    • 乘法操作:字符串乘以数字,实现重复多少次此字符串;

    • 比较运算:==、!=、<、>等,按编码大小比较;

    • 索引操作:格式:容器[整数],根据索引获取指定位置字符串,索引从零开始;

      aa = "hello world"
      print(aa[4])
      o   # 输出结果
      
    • 内建函数:

      • len函数,获取序列的长度:
        • 正向索引:len(字符串) - 1,从 0 开始;
        • 反向索引:- len(字符串),从 -1 开始。
      • max函数,最大值;
      • min函数,最小值;
      • sum函数,求和;
    • 切片操作:slice、split,格式:容器[开始:结束:间隔],包含开始,不包含结尾;

      aa = "hello world"
      print(aa[1:6])
      ello        # 输出结果,正常输出
      
      print('{!r}'.format(aa[1:6]))
      'ello '     # 输出结果,格式化为带引号输出
      
      print(aa[:3])     # 前三个,简写
      print(aa[-3:])     # 后三个,简写
      print(aa[::-1])     # 倒序输出
      print(aa[::1])     # 正序输出
      
    • 包含:in、not in,例如:“ell” in “hello” ,结果为布尔值 True;

  2. 字符串 str:由一系列字符组成,存储的是字符的编码值!

    • id函数:返回对象真实内存地址;

    • ord函数:返回字符对应的 Unicode 编码值,例如:ord(“s”);

    • chr函数:返回整数对应的字符串,例如:chr(114);

    • 单引号 Single quotes:'hello world'

    • 双引号 Double quotes:"hello world"

    • 三引号 Triple quoted :长字符串,实现换行字符串

      triple_quotes = '''hello world'''
      triple_quotes = """hello world"""
      
    • 转义字符:用于表示一些不能直接显示的ASCII字符,使用 \ 开头;

    • 原始字符串:表示字符串中没有转义符

      转义字符需要正常使用,不作为转义字符时,可以在前面加上r,转义不生效;

      print("D:\one\two\three")
      D:\one  wo  hree    # 输出结果
      
      print(r"D:\one\two\three")
      D:\one\two\three    # 输出结果
      
    • 字符串格式化:

      • 格式:"…%s…%d…%f…"%(变量1, 变量2, 变量3),运行时会自动将变量插入对应位置中;
      • 使用 % 类型码占位,%s 指字符串,%d 指整数,%f 指小数;
      • %2s 指规定占位符长度为 2,%.2f 指保留 2 位小数(四舍、六入、五平分)
  3. 列表 list:由一系列变量组成的可变序列容器

    • 格式一:容器名 = [],内部放对象,使用逗号分隔;
    • 格式二:容器名 = list(),参数放可迭代对象,将对象按索引分为多个对象;
    • 添加:append函数;
    • 插入:insert函数,参数一为下标,参数二为插入对象;
    • 修改:容器名[索引] = 数据值,也可以使用切片修改多个值,如:list01[2] = “你好”、list01[-2:] = [1, 2];
    • 删除:remove函数,参数为元素;或使用 del 语句,根据索引,切片删除;
    • 循环:for语句;
      • 建议使用索引操作,因为切片会创建新的列表,浪费内存;
      • 正序:range(len(列表名)),通过索引才能操作每一项数据;
      • 倒序:range(len(列表名) - 1, -1, -1)
    • 深浅拷贝:
      • 浅拷贝:list中的copy函数,或使用切片操作,浅拷贝等于切片;
      • 深拷贝:导入 import copy,使用copy.deepcopy(列表);优点:不影响原数据;缺点:占内存;
      • 区别:浅拷贝只复制新列表,重新引用已有的变量;深拷贝则是复制所有的列表及存储的变量;
    • 循环删除:使用倒序删除,否则会有漏删、下标越界问题出现;
    • 列表推导式:简洁方式构建列表;
      • 格式一:变量 = [表达式 for 变量 in 可迭代对象]
      • 格式二:变量 = [表达式 for 变量 in 可迭代对象 if 条件],if条件不满足则丢弃当前项;
      • 例如:list2 = [item for item in list1]、list2 = [item for item in list1 if item > 20]
    • 列表与字符串的转换:
      • 列表转字符串:join函数,例如:result = “连接符”.join();
      • 字符串转列表:split函数,例如:list01 = “字符串”.split(“分隔符”);
  4. 元组 tuple:由 变量 组成的不可变序列,无法增删改;

    • 格式一:tuple1 = (),注意:一个大小的元组创建:tuple1 = (元素, ),不写逗号表示元素原始的类型;
    • 格式二:tuple1 = tuple(可迭代对象);
    • 格式三:tuple1 = 100, 200, 300,可省略括号,不建议;
    • 查询:x, y = tuple1,指将元组中数据前两位赋值给 x 和 y;
      • **变量交换的本质 **就是创建元组,例如:x, y = (y, x)
      • 格式化字符串的本质 就是创建元组,例如:“…%s…%d…” % (name, age)
    • 索引
    • 切片
    • 循环
  5. 字典 dict:由 键值对 组成的可变散列容器,无序的;优点:查改最快;

    • 格式一:dict1 = {},键值对 使用冒号分隔,例如:“name” : “Bob”;
    • 格式二:dict1 = dict( 可迭代对象 ),格式:dict1 = dict([(“name”, “zs”), (“age”, 23)]),建议使用方括号;
    • 字典转列表:list(dict1),结果只会将键存储进列表,值将会丢弃;
    • 添加 / 修改:字典名[“键”] = 值,如果键不存在则添加,存在则是修改;例如:dict1[“name”] = “zs”
    • 查询:字典名[“键”],根据 键 获取 值,如果 键 不存在则报错
      • 获取键:for 键 in 字典名
      • 获取值:for 值 in 字典名.values()
      • 获取键值对:
        • for kv in 字典名.items(),获得的是元组;
        • for 键, 值 in 字典名.items(),分别获取键和值;
    • 删除:del语句,例如:del dict1[“name”],如果 键 存在则删除,如果 键 不存在则报错;
    • 字典推导式:建议转换可迭代对象为字典;
      • 格式一:变量 = {键 : 值 for 变量 in 可迭代对象}
      • 格式二:变量 = {键 : 值 for 变量 in 可迭代对象 if 条件}
  6. 集合 set:由 不重复的不可变类型变量(元组/数/字符串)组成的可变散列容器,即只有 键 的字典;

    • 格式一:set1 = {“值1”, “值2”},此方式不能创建空集合;
    • 格式二:set1 = set(可迭代对象),唯一的创建空集合方式;
    • 增加:add函数,例如:set1.add(“key”);
    • 删除:
      • remove函数,存在则删除,否则报错;先判断在删除!!!
      • discard函数,存在则删除,不存在不报错!
    • 数学运算
      • 交集 & :取出两个集合中相同的元素;set1 & set2
      • 并集 | :取出两个集合中不重复的元素;set1 | set2
      • 补集 ^ :取出两个集合中除去相同的元素后剩余的元素;set1 ^ set2
      • 减法 - :取出集合 1 有的而集合 2 没有的,set1 - set2
      • 子集 < :判断集合 2 是否包含集合 1 ,set1 < set2
      • 超集 > :判断集合 1 是否包含集合 2 ,set1 > set2
  7. 固定集合 frozenset:不可变的集合;

    • 用于对列表的去重复,相对来说节省内存;
  8. 嵌套循环 for for:外层循环一次,内层循环一轮;

    • 列表排序:

      list1 = [55, 66, 99, 54, 33, 98, 15, 22, 78]
      # 排序
      for i in range(len(list1) - 1):
          for j in range(i + 1, len(list1)):
              if list1[i] > list1[j]:
                  list1[i], list1[j] = list1[j], list1[i]
      
    • 列表推导式嵌套循环:实现列表的全排列;

      # 制作扑克牌
      numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
      colors = ["黑桃♠", "梅花♣", "方块♦", "红桃♥"]
      
      puker = [i+j for i in numbers for j in colors]
      puker.append("大王🃏")
      puker.append("小王🃏")
      

七、函数 function

  1. 定义函数:

    • 格式一:def 函数名(): 函数体
    • 格式二:def 函数名( 形式参数 ): 函数体
    • 格式三:def 函数名( 形式参数 ): 函数体 return 返回值
    • 在函数体第一行使用注释说明函数的作用;
  2. 调用函数:就近原则,重复的函数优先调用近的;

    • 格式一:函数名()
    • 格式二:函数名( 实际参数 )
    • 格式三:变量 = 函数名( 实际参数 ),接收返回值,默认值为None;
  3. 内存图:

    • 函数加载:将函数代码存储到内存代码区;
    • 调用函数:在内存中开辟一块空间 (栈帧),存储函数中定义的变量;
    • 调用结束:栈帧释放;
  4. 传参说明:

    • 不可变类型的数据 (数值型、布尔值bool、空值None、字符串str、元组tuple、固定集合frozenset),函数内部不会改变原数据的值;

    • 可变类型的数据 (列表list、字典dict、集合set),函数内部可以改变原数据的值;

  5. 作用域:变量起作用的范围

    • 全局作用域 global:整个文件中可用,若在函数中,可使用 global 关键字声明变量为全局;
    • 局部作用域 local:只能在函数中使用,调用结束销毁;
    • 外部嵌套作用域 enclosing:函数嵌套;
    • 内置模块作用域 builtin:builtins.py文件,优先级很高;
  6. 变量的查找规则:

    • 由内到外:局部 – 外部嵌套 – 全局 – 内置模块;
  7. 函数参数:

    实际参数

    • 位置实参

      ​ 调用函数时,实参根据位置与形参对应;

      • 序列实参:例如:fun01(*list01)
        • 使用 * 拆分序列元素,再根据位置与形参对应;
        • 作用:参数过多时,可以通过容器传递信息;
        • 只要是可迭代对象都可以拆分!但是传递散列无意义,无法正确对应位置关系;
    • 关键字实参

      ​ 实参根据名称与形参进行对应;可读性提高,例如:fun01(p1=“”, p2=0, p3=0.0)

      • 字典实参:例如:fun01(**dict01)
        • 根据键对应实参名称去对应;
        • 使用 ** 拆分序列元素,再根据 键名 对应实参名称去对应值;

    形式参数

    • 缺省参数:默认参数,例如:fun01();

      def fun01(p1="", p2=0, p3=2.0):
      
    • 实参可以不传递,采用默认值;

      • 必须 从右往左 依次存在,否则报错;
      • 关键字实参 + 默认参数:实现随意传参,例如:fun01(p2 = 100),p1, p3取默认值;
    • 位置形参

      • 实参必须传递;

      • 星号元组形参

        def fun01(*args):
            pass
        fun01(1,2,3,5,9)
        
        • 使用 * 将实参合并为一个元组;只能有一个参数!
        • 作用:位置实参数量不限个数;
    • 命名关键字形参

      def fun01(*args, p1, p2):	# 可以使用默认参数赋值
          
      def fun01(p1, *, p2):		# 注意:p1可使用位置形参,p2必须使用关键字形参
      
      • 星号元组形参后面的参数;

      • 要求实参必须是关键字实参;例如:fun01(1,2,3,5,p1=7,p2=9);

      • 双星号字典形参

        def fun01(**kwargs):
        
        • 目的:使关键字实参不限制数量;
    • 万能参数写法:

      def fun01(*args, **kwargs):
          pass
      

八、常用API

官网文档:https://docs.python.org/zh-cn/3.10/

菜鸟教程:https://www.runoob.com/python3/python3-tutorial.html/

九、面向对象

抽象:类别,例如:狗类

具体:个体,例如:哈士奇

程序的设计:先有对象,再有类;

编写的代码:先有类,再有对象;

面向过程:function 称为(函数)

面向对象:function 称为(方法)

  1. 类的创建:

    • 成员变量:数据,例如:名字、年龄、性别等;

    • 成员方法:行为,例如:吃饭、洗澡、玩游戏等;

    • 格式:

      class 类名:
          def __init__(self, 成员变量……):
              self.实例变量 = 参数
          def 成员方法:
              ……
      
      class Dog:
      	def __init__(self, name, age, sex):
              self.name = name
              self.age = age
              self.sex = sex
      
          def eat(self):
              print(self.name, "吃饭")
      
  2. 创建对象:

    • 格式:对象名 = 类名(参数),也称为:对象名 = 构造函数(参数)

      • 构造函数:__init__ 方法,创建对象时自动调用,没有成员变量时可以省略不写;
    • 调用类的方法:对象名 . 方法名()

      dog01 = Dog("小白", 5, "雌")		# 创建对象
      dog01.eat()		# 调用类中的方法
      
    • 内存图:

      • 首先根据变量的数据个数来开辟内存空间;

      • self 指向的是开辟空间的内存位置,可以通过 print(id(self)) 查看地址值,结果与创建的对象地址值相同!!

  • 所有的函数每次调用都会开启一个栈帧,调用结束,栈帧销毁;

  • 调用方法默认会将 自身的对象 self 传入方法中,例如:dog01.eat() 等价于 dog01.eat(dog01);
    原理

  1. 实例成员:

    • 实例变量:
      • 创建:对象.变量名,例如:self.name = name
      • 调用:对象.变量名,例如:dog01.name = “tom”
    • 说明:
      • 首次赋值为创建,再次赋值为修改;
      • 通常在构造函数中创建;
      • 每个对象存储一份,通过对象的地址访问;
      • __dict__ 用于访问类中所有的数据,返回一个字典,例如:dog01.__dict__;不建议赋值操作;
  2. 实例方法:

    • 语法:
      • 定义:def 方法名(self, 参数列表): 方法体
      • 调用:对象地址.方法名(参数列表);
      • 使用类名访问实例方法,例如:Dog.eat(dog01);不建议使用!!
    • 说明:
  • 实例方法至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为self
    • 无论创建多少对象,方法只有一份,且被所有对象共享。
  • 作用:表示对象的行为;
  1. 类成员:

    • 类变量:

      • 位置:类中方法外;

      • 调用:类名.变量名;

        class Cat:
            total_money = 1000
        
        Cat.total_money = 0		# 调用
        
    • 类方法:

      • 格式:普通方法上添加注解:@classmethod,默认接收一个参数 cls 为当前的类名;

      • 作用:操作类变量;

      • @classmethod 作用:调用类方法时,隐式传递类;

        class Cat:
            total_money = 1000
            
            @classmethod
            def print_money(cls):
                print(Cat.total_money - 500)  # 操作类变量,类名.变量名
                print(cls.total_money - 500)  # 接收的参数就是当前的类名!
                
        Cat.print_money()		# 调用
        
    • 特点:

      • 随类的加载而加载;
      • 优先于对象存在;
      • 所有对象可以共享类变量 / 类方法;
      • 只能有一份;
  2. 静态方法:

    1. 语法:

      1. 定义

        @staticmethod
        def 方法名(参数):
            方法体
        
      2. 调用:类名.方法名(),不建议通过对象访问静态方法;

    2. 说明:

      1. 使用 @staticmethod 修饰的目的是 该方法不需要隐式 ( 默认的参数 ) 的传参;
      2. 静态方法不能访问实例成员和类成员;
    3. 作用:

      • 常常用于封装工具函数;

十、三大特征:封装、继承、多态

  1. 封装

    1. 数据角度:

      • 定义:将一些基本数据类型复合成一个自定义类型;
      • 优势:
        • 将数据与对数据的操作相关联;
        • 代码可读性更高;
    2. 行为角度:

      • 定义:类外提供必要的功能,隐藏实现的细节;

      • 优势:

        • 简化编程,使用者无需知道具体的实现细节,只需调用对外提供的功能;
      • 私有成员:

        • 作用:无需向类外提供的成员

        • 做法:

          • 命名使用双下划线开头;例如:self.__age

            • 障眼法:访问时,实际是 _类名 + 私有变量名 ( _Wife__age ),不建议这样访问;
          • 定义公开的读取方法,判断数据内容;get***()

          • 定义公开的写入方法,写入时做判断;set***()

          • 类变量指向 property() 对象,格式:类变量 = property(get**, set**),将对数据的操作转为对方法的操作;

          • 最终版本

            • get方法:添加注解 @property,同时方法名与实例变量一致;
            • set方法:添加注解 @变量名.setter,同时方法名与实例变量一致;
            class Student:
                def __init__(self, name):
                    self.name = name
            
                @property
                def name(self):
                    return self.__name
            
                @name.setter
                def name(self, name):
                    self.__name = name
            
    3. 设计角度:

      • 定义:
        • 分而治之:大需求分解为许多个类,各自处理一个独立的功能;
        • 变而疏之:变化的地方独立封装,避免影响其他类;
        • 高内聚:类中各个方法都在完成一项任务(单一职责)
        • 低耦合:类与类的关联性与依赖度要低(每个类独立)
      • 优势:便于分工,便于复用,可扩展性强;
  2. 继承:重写现有类的功能,并在此基础上进行扩展;

    格式:class 类名( 父类类名 ): ……

    优点:提升代码复用性;

    缺点:耦合度高,父类变化直接影响子类;

    1. 语法角度:

      • 继承方法:子类可以使用父类的方法;

      • 继承数据:

        • 子类没有构造函数,将会使用父类的构造函数;
        • 子类有构造函数,将会覆盖父类的构造函数;
        • 需要使用父类的构造函数,使用 super().__init() 调用父类的构造函数;
      • 重写

        • 子类实现父类中相同的方法 (方法名、参数) ,在调用该方法时,实际调用的是子类重写的方法;

        • 内置可重写函数:以双下划线开头,双下划线结尾的是系统定义的成员;

          • 转换字符串

            • __str__() 函数:将对象转换为字符串显示,对人友好的;类似toString方法;

            • __repr__() 函数:将对象转换为字符串显示,对解释器友好的;搭配 eval 函数

              • eval() 函数:将字符串作为python代码执行(python的灵活之处

                print(eval('3+5*3'))	# 直接将字符串作为代码运行,输出结果
                car1 = Car('吉利汽车', 50000)
                car2 = eval(car1.__repr__())	# 克隆对象
                
          • 运算符重载:运算后返回新对象地址

            • __add__(self, rhs):对象之间相加的方法,self + rhs;

            • __sub__(self, rhs):减法,self - rhs;

            • __mul__(self, rhs):乘法,self * rhs;

            • __truediv__(self, rhs):除法,self / rhs;

            • __floordiv__(self, rhs):除法 (地板除) ,self // rhs;

            • __mod__(self, rhs):取模 (求余) ,self % rhs;

            • __pow__(self, rhs):幂,self ** rhs;

              class Vector1:
                  def __init__(self, x = 0):
                      self.x = x
                      
                      def __add__(self, rhs):		# 重写
                          return Vector1(self.x + rhs.x)
              
          • 复合运算符重载:运算后返回原对象地址,原来的基础上做运算!

            • __iadd__(self, rhs):加等于,self += rhs;

            • 其他运算符与上类似,在普通运算符方法前加 i 即为复合运算符方法……

              class Vector1:
                  def __init__(self, x = 0):
                      self.x = x
                      
                      def __iadd__(self, rhs):		# 重写
                          self.x += rhs.x
                          return self
              
          • 比较运算符重载

            • __eq__(self, rhs):比较,self == rhs;常用方法eq;
              • == 和 is 的区别:
                • ==:判断的是 __eq__() 方法中的内容;
                • is:判断的是地址值,两个对象的 id(对象) 方法;
          • 反向运算符重载

            • __radd__(self, rhs):加法,self + rhs;

              class Vector1:
                  def __init__(self, x = 0):
                      self.x = x
                      
                      def __radd__(self, rhs):		# 重写
                          return self.x + rhs
                      
              
              print(v01 + 10)		# 重写了__add__()可用
              print(10 + v01)		# 报错,10不能重写__add__(),只能对象去重写__radd__()
              
    2. 设计角度:

      1. 定义:将相关类的共性进行抽象,同一概念,隔离变化;
      2. 适用性:
    3. 内置函数:

      • type(对象):判读对象的类型;
      • isinstance(对象,类型):XX对象 是否是 一种XX类型;
      • issubclass(类型,类型):XX类型 是否是 一种 XX类型;
      • ==:XX对象 是否是 XX类型;
    4. 多继承:

      1. 定义:一个子类同时继承两个以上的父类;被多个变化所隔离,不是代码的复用!
      2. 注意:
        • 如果父级别有多个重名方法,调用时使用的时继承列表最左边的类的方法;
        • 如果想要使用其他父类的方法,则使用类名访问,例如:B.fun01(self);
        • 同名方法解析顺序,使用 mro() 函数查看;
  3. 多态

    1. 语法角度
    2. 设计角度:
      • 定义:父类的同一种动作或行为,在不同的子类上有不同的实现;
      • 作用:

十一、六大原则:

  1. 开闭原则:对扩展开放,对修改关闭。可以增加新功能,但是不能修改原有代码;
  2. 依赖倒置:调用父类,而不是子类;
  3. 组合复用:代码复用优先选择组合关系,而不是继承,代码更灵活;
  4. 单一职责:一个类的定义,有且只有一个改变的原因;
  5. 里氏替换:参数为父类,传参传子类,但要保持原功能,子类重写时先调用父类方法,再写扩展功能;
  6. 迪米特法则:不与陌生人说话。类与类交互时,传递数据量越少越好,类与类互不影响;

Python基础学习笔记(二)

  • 44
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风於尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值