《深入理解Python特性》读书笔记

读书笔记

《深入理解Python特性》的读书笔记

代码整洁

  • 遵循PEP8的代码规范连接
  • 在终端使用import this查看python之禅

Python 中下划线的使用

单前导下划线 _var

  • 单个下划线是一个Python命名约定,表示这个名称是供内部使用的。 它通常不由Python解释器强制执行,仅仅作为一种对程序员的提示。
  • 一般用于类中保护类型的声明

单末尾下划线 var_

  • 单末尾下划线是PEP8中约定的防止命名冲突的方式

双前导下划线 __var

  • 用于名称修饰,就是给改名防止冲突
  • 主要用于类成员中私有类型的声明

双前导双结尾下划线 var

  • 主要表现在类的魔法函数上,这种命名的函数都有其固定的功能,不建议变量使用这种命名方式
  • 魔法函数如:
    • __init__,构造函数
    • __str__,类被当作字符串输出时调用
    • __call__,类被当作方法时调用

单独一个下划线

  • 按照习惯’_'代表的不关心的值
  • 一般用于for循环的迭代次数
  • 或者是解包的时候占位

使用断言

  • 断言语句assert 条件
    • 如果条件为真,则代码正常执行,如果条件为假,则程序停止触发一个AssertionError的异常。
    • 使用断言仅仅是为了增加一层保险,同时方便出错后的调试。
    • 注意:断言不是一个错误处理机制,只是为了当程序发生了不可恢复错误时的自检调试

字符串的格式化

  • 仔细看来python中字符串的格式化还真的不少

    • 使用类C语言的方式

      "hello %s" % name
      
      # 如果存在多个需要使用元组包裹
      "hello %s , %s" %(name1,name2)
      
    • 使用format()函数

      "hello {}".format(name)
      # 可以使用关键字参数
      "hello {name}".format(name="word")
      
    • python3.6+的时候可以使用字符串插值的方式

      f"hello {name}"
      # 会默认将 name 的值插入到指定位置
      
    • 使用模板字符串

      from string import Template
      name = "word"
      t = Template('Hello',$name)
      t.substitute(name=name)
      # 输出结果为 Hello word
      # 使用模板字符串的时候会按照传参进行替换
      

函数部分

  • 函数也是对象,可以放入容器,或者被当作参数传给其他函数
  • 函数可以嵌套,内部函数只是在函数内可见,外部无法访问
  • 函数的可捕获状态
    • 内部函数可以捕获并且携带父函数的某些状态,装饰器就是基于这一点
  • 对象可以被当作函数使用,只要他实现了__call__方法
  • 函数默认返回值为None,即所有函数都是有返回值的,不写就是None
  • lambda x:x+1表示就是匿名函数
    • 冒号前的x为参数,参数可以多个
    • 默认会将冒号后的表达式计算的结果当作返回值
    • lambda只适合简单的逻辑,复杂的函数尽量不要使用,不方便维护。
  • 使用装饰器时尽量使用functools.wraps,来包装自己的装饰器
  • 装饰的调用遵循栈式规则,即先调用下面的装饰器,后调用上面的。
  • ***用于解包
    • *用于解元组、列表
    • **用于解字典

类和面向对象

  • 对象比较==is

    • is判断的是否是同一个变量,即内存地址是否是一个
    • ==判断是值是否一样
  • 对象的__repr__方法

    • 这个方法是用来说明一个类的‘
    • 如果在未实现__str__方法的适合默认会调用这个方法
    • 尽量为每一个类添加这个方法,方便代码调试时的输出。
  • 克隆对象引用、浅拷贝和深拷贝

    • 引用就是创建将原来的对象起了个别的名字,使用的内存还是原来的那个

    • 浅拷贝,比如使用:

      x = [[1,2,3],[4,5,6]]
      y = list(x)
      
      • 这时y就是x的浅拷贝
      • 此时使用x is y得到的结果是False
      • 如果改变y中某个元素的值,x中的值也会改变
  • 深拷贝

    • 使用模块import copy

      import copy
      x = [[1,2,3],[4,5,6]]
      y = copy.deepcopy(x)
      
      • 此时得到的yx的深拷贝
      • 这是使用x is y得到是False
      • 并且如果修改了y中元素的值,x中的元素值保持不变。

使用抽象基类指定接口

from abc import abstractmethod,ABCMeta

class Base(metaclass=ABCMeta):
    
    @abstractmethod
    def foo(self):
        pass
  • 此时继承这个类的子类必须实现foo(全部抽象方法)这个方法,否则这个类将不能实例化

使用命名元组

  • collection.namedtuple能够方便的在Python中定义一个带名字的元组对象。
  • 使用namedtuple可以更轻易的理解数据结构,从而简化代码
  • 一般用于定义一个不可变的类,并且这个类占用内存较小。

类中的方法

  • 实例方法
    • 在类中正常定义的方法为实例方法
    • 实例方法在使用的时候需要一个实例
    • 实例方法的第一个参数是self代表实例本身
  • 类方法
    • 使用@classmethod装饰器装饰的函数为类方法
    • 类方法可以被类访问
    • 类方法的第一个参数为cls代表类本身
  • 静态方法
    • 使用@staticmethod装饰器装饰的方法是静态方法
    • 静态方法不接受selfcls参数,但可以接收其他任意参数
    • 他的作用和普通函数一样,但属于类的命名空间
  • 属性方法
    • 使用@property装饰的函数
    • 这种函数可以像访问属性一样访问
    • 一般用于得到某个需要计算的属性时使用

Python中的数据结构

集合

  • 集合是python及其标准库中含有的另一种有用的数据结构
  • 查找可变集合可以使用set,集合中的元素不允许重复
  • frozenset对象可散列化能够作为字典和集合的键
  • collections.Counter实现了多重集合或者背包类的数据

  • pythonlist即可看作简单的栈
  • collections.deque一个快速且稳健的栈结构
  • queue.LifoQueue一个为多线程准备的栈,提供了锁操作

队列

  • 列表也可以看作队列,只是这个队列会非常慢
  • collections.deque提供一个快速稳健的队列
  • multiprocessing.Queue共享作用的队列

优先队列

  • heapq是一个二维堆
  • queue.PriorityQueue一个快速而稳健的优先队列,并且提供了锁语句来支持并发。

高效技巧

  • 使用dir查看类中的全部属性
  • 使用help查看帮助文档
  • 使用virtualenv来创建虚拟环境
  • 使用功能强大的字典

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