《Python基础教程》第6~8章 学习笔记

时间:2021-07-23 23:52:25

Python 6-8章

tags: Python Learning Note


第6章 抽象

  • 6.3 创建函数
      1. `callabel()`可以测试函数能否调用。(返回True/False)(3.0得用`hasattr(func, __cal__)`代替)   
    2. 使用`def`语句定义函数
    • 6.3.1 记录函数
      直接写上字符串,比如在def语句后面,称为文档字符串。
      可以使用内建help得到关于函数的信息,包括文档字符串。
    • 6.3.2 并非真正函数的函数
      return起到结束函数的作用。
  • 6.4 参数魔法 这正是Python的魅力所在!
    • 6.4.1 值从哪里来(实参与形参)
    • 6.4.2 我能改变参数吗
      这里有一篇写得不错的文章:Python的函数参数传递:传值?引用?
    • 6.4.3 关键字参数和默认值
      关键字参数:参数很多的时候,参数的顺序很难记住,可以提供参数的名字。
      默认值:同C一样,定义函数时可以为参数提供默认值。
    • 6.4.4 收集参数
      收集参数:用*+参数名收集其余的位置参数为一个元组。(没有就是一个空元组)
      关键字参数:**+参数名收集有关键字的参数,得到一个字典。
        普通参数和关键字参数可以联合使用。
    • 6.4.5 反转过程
      函数收集的逆过程,在调用而不是在定义时使用。
        def add(x, y): return x + y
      params = (1, 2)
      add(*params)
      同样字典也可以用**翻转
      这里的拼接Splicing不是很懂,mark下
  • 6.5 作用域
    变量可以看做是值的名字,然变量-所对应的值是个”不可见“的字典。内建的vars 函数可以返回这个字典。
      scope = vars()
    一般来说,vars所返回的字典是不能修改的,结果是未定义的,可能得不到想要的结果
    这种“字典”就是作用域。
    可以直接引用全局变量。但最好还是用global访问,如果内外作用域变量名重叠了,可以用globals()['parameter']获取。
    作用域是可以嵌套的。这里有一个闭包的概论,闭包是一个包含有环境变量取值的函数对象。环境变量取值被保存在函数对象的__closure__属性中。关于闭包具体见这篇博文:Python 学习入门(25)—— 闭包
  • 6.6 递归
    自身调用自身。
      标准库中的bisect模块可以非常有效地实现二元查找。
    “函数式编程”方面的函数:map、filter 和 reduce 函数(3.0中被移到 functools 模块中)
    lambda:匿名函数。 map:将序列中的元素全部传递给一个函数。list(map(str,range(10)))
    filter:基于一个返回布尔值的函数对元素进行过滤。list(filter(lambda x:x.isalnum(), seq))
    reduce:对一个序列的每个项迭代调用函数。它会将序列的两个元素与给定的函数联合使用,并且将它们的返回值和第3个元素继续联合使用,直到整个序列处理完毕。reduce(lambda x,y:x+y,numbers)
    这边有一篇关于Python的函数式编程的简单介绍:python的函数式编程玩法+年末小感

第7章 更加抽象

  • 7.1 对象的魔力
    这书类都没讲竟先讲然这些特性,真太挫,不想多说 仨特性:多态 封装 继承
  • 7.2 类和类型

    • 7.2.1 类到底是什么 超类(superclass)就相当于c++里面的父类或基类。
    • 7.2.2 创建自己的类 在模块或脚本开始的地方放置语句 __metaclass__
      = type
      表示新式类。

      关于new_sytle class详见啄木鸟社区的译文:python中的 new-style class 及其实例详解

      class语句会在函数定义的地方创建自己的命名空间
      self是对于对象自身的引用

        如果知道foo是Person的实例的话,还可以把foo.greet()看做Person.greet(foo)方便的简写
    • 7.2.3 特性、函数和方法
      方法(更专业一点可称为绑定方法)将它们的第一个参数绑定到所属的实例上,因为这个参数可以不必提供。
      self 参数并不取决于调用方法的方式。
      在类的内部定义中,双下划线开始的名字被“翻译”成前面加下划线和类名的形式。
    • 7.2.4 类的命名空间
      类作用域的对象可以被所有实例访问。
      重新绑定里面的特性会屏蔽类范围内的变量。
    • 7.2.5 指定超类
      claass A(B): ...,B是A的超类,A是B的子类。 子类正常会重写超类的方法。
    • 7.2.6 调查继承
      issubclass函数:查看一个类是否是另一个的子类。
      isinstance函数:检查一个对象是否是一个类的实例。 __bases__特性:想要知道已知类的基类。
      __class__:查看一个对象属于哪个类。
      如果是新类的话,可以用type函数来查看实例的类。
    • 7.2.7 多个超类
      多重继承,注意:先继承的类中的方法会重写后继承的类中的方法。
      MRO(Method Resolution Order,方法判定顺序):查找给定方法或者特性时访问超类的顺序。
    • 7.2.8 接口和内省
      检查所需方法是否已经存在:hasattr(obj, 'method')
      检查特性是否可调用:callable(getattr(obj, 'method', None))(在3.0中可以使用hasattr(x, '__call__')来代替callable(x)
      __dict__特性:查看对象内所以存储的值。

第8章 异常

  • 8.1 什么是异常
    每个异常都是一些类的实例,这些实例可以被引发,并且可以用很多种方法进行捕捉,使得程序可以捉住错误并且对其进行处理,而不是让整个程序失败。
  • 8.2 按自己的方式出错
    • 8.2.1 raise语句
      可以使用一个Exception的子类或者实例参数调用raise语句。
      可以用dir(exceptions)查看内建的异常。(需要import exceptions
    • 8.2.2 自定义异常类
        class SomeCustomException(Exception): pass
  • 8.3 捕捉异常
    try/except 异常实现。
      如果没有捕捉到异常,它会被“传播”到调用的函数中。如果那里依然没有捕获,这写异常就会“浮”到程序的最顶层。
    如果要传递异常,可以使用raise
  • 8.4 不止一个except子句
    try/expect 异常可以附带多个expect
  • 8.5 用一个块捕捉两个异常
    try/expect (...)将异常作为元组放进去
  • 8.6 捕捉对象
    捕捉产生的异常对象:try/ except (...), e(3.0是 as e
  • 8.7 真正的全捕捉
    try/ expect可以捕捉全部异常。
      注意:这样捕捉所有异常是危险的,因为它会隐藏所有程序员未想到并且未做好准备处理的错误。使用except Exception,e会更好,或者对异常对象e进行一些检查
  • 8.8 万事大吉
    try /expect /else进行没有异常情况的处理。
    下面是一个简单计算除法的代码:
    while True:             # 如果出错必须重新输入,否则无法跳出循环
    try:
    x=input('Enter the first number: ')
    y=input('Enter the second number: ')
    print(int(x)/int(y))
    except Exception as e : # 如果出错了,打印错误信息
    print(e)
    print('Invalid input,please try again')
    else: # 计算过程没有异常,跳出
    break
  • 8.9 最后
    try/except/else/finally:无论是否发生异常情况,都需要执行一些清理工作。(如通信过程)
  • 8.10 异常和函数
  • 8.11 异常之禅
    有时候用异常会比if/else效率快。