Python知识手册(更新中)

......

Posted by 呆贝斯 on August 27, 2018

Python解释器种类以及特点

Python是一门解释型语言,代码需要通过解释器才能执行,Python存在多种解释器, 分别基于不同语言开发,每个解释器有不同的特点,但都能正常运行Python代码。

  • CPython:官方版本的解释器:CPython。这个解释器是用C语言开发的,所以叫CPython。 在命令行下运行python就是启动CPython解释器。CPython是使用最广且被的Python解释器。
  • IPython:IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强, 但是执行Python代码的功能和CPython是完全一样的。CPython用»>作为提示符,而IPython用In [序号]:作为提示符。
  • PyPy:PyPy是另一个Python解释器,它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释), 所以可以显著提高Python代码的执行速度。绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的, 这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。如果你的代码要放到PyPy下执行,就需要了解PyPy和CPython的不同点。
  • Jython:Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
  • IronPython:IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

什么是pep?

pep全称是Python Enhancement Proposals,其中Enhancement是增强改进意思,Proposals则可译为提案或建议书。 Python核心开发者主要通过邮件列表讨论问题、提议、计划等,PEP通常是汇总了多方信息, 经过了部分核心开发者review和认可,最终形成的正式文档,起到了对外公示的作用。

无论你是刚入门Python的小白、有一定经验的从业人员,还是资深的黑客,都应该阅读Python增强提案,阅读PEP至少有如下好处:

  1. 了解Python有哪些特性,它们与其它语言特性的差异,为什么要设计这些特性,是怎么设计的,怎样更好地运用它们。
  2. 跟进社区动态,获知业内的最佳实践方案,调整学习方向,改进工作业务的内容。
  3. 参与热点议题讨论,或者提交新的PEP,为Python社区贡献力量。

说到底,学会用Python编程,只是掌握了皮毛。PEP提案是深入了解Python的途径,是真正掌握Python语言的一把钥匙,也是得心应手使用Python的一本指南。

Python中的命名空间是什么?

python命名空间 命名空间,即Namespace,也成为名称空间或名字空间,指的是从名字到对象的一个映射关系,类似于字典中的键值对, 实际上,Python中很多命名空间的实现用的就是字典。不同命名空间是相互独立的,没有任何关系的, 所以同一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。

Python命名空间按照变量定义的位置,可以划分为以下3类:

  • Built-in,内置命名空间,python自带的内建命名空间,任何模块均可以访问,存放着内置的函数和异常。
  • Global,全局命名空间,每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块、模块级的变量与常量。
  • Local,局部命名空间,每个函数、类所拥有的命名空间,记录了函数、类中定义的所有变量。

一个对象的属性集合,也构成了一个命名空间。但通常使用objname.attrname的间接方式访问属性,而不是直接访问,故不将其列入命名空间讨论。 (直接访问:直接使用名字访问的方式,如name,这种方式尝试在名字空间中搜索名字name。 间接访问:使用形如objname.attrname的方式,即属性引用,这种方式不会在命名空间中搜索名字attrname,而是搜索名字objname,再访问其属性。)

不同类型的命名空间有不同的生命周期:

  • 内置命名空间在Python解释器启动时创建,解释器退出时销毁;
  • 全局命名空间在模块被解释器读入时创建,解释器退出时销毁;
  • 局部命名空间,这里要区分函数以及类定义。函数的局部命名空间,在函数调用时创建, 函数返回结果或抛出异常时被销毁(每一个递归函数都拥有自己的命名空间); 类定义的命名空间,在解释器读到类定义(class关键字)时创建,类定义结束后销毁。

Python的LEGB规则

  • L-Local(function):函数内的名字空间
  • E-Enclosing function locals:外部嵌套函数的名字空间
  • G-Global(module):函数定义所在模块(文件)的名字空间
  • B-Builtion(Python):Python内置模块的名字空间

Python的命名空间是一个字典,字典内保存了变量名称与对象之间的映射关系,查找变量名就是在命名空间字典中查找键值对。 Python有多个命名空间,需要有规则来规定按照总样的顺序来查找命名空间,LEGB就是用来规定命名空间查找顺序的规则。 LEGB规定了查找一个名称的顺序为:local –> enclosing functions locals –> global –> builtin。

什么是Python中的文档Docstrings?

DocStrings 文档字符串是一个重要工具,用于解释文档程序,帮助你的程序文档更加简单易懂。 我们可以在函数体的第一行使用一对三个单引号 ''' 或者一对三个双引号 """ 来定义文档字符。 Docstrings 不是技术性的注释。当 Docstrings 在模块,函数,类,或者方法的前面出现的时候, 它在字节码中结束,并且变成__doc__特殊属性的对象。 DocStrings 文档字符串使用惯例:它的首行简述函数功能,第二行空行,第三行为函数的具体描述。

""" 简述函数功能
    
    函数的具体描述。
"""

什么是PYTHONPATH?

PYTHONPATH是Python中一个重要的环境变量,用于在导入模块的时候搜索路径,可以通过如下方式访问。

import sys
print(sys.path)

由于在导入模块的时候,解释器会按照sys.path列表的顺序搜索,直到找到第一个模块,所以优先导入的模块为同一目录下的模块。 导入模块时搜索路径的顺序也可以改变.这里分两种情况:

  1. 通过sys.path.append(),sys.path.insert()等方法来改变,这种方法当重新启动解释器的时候,原来的设置会失效。
  2. 改变PYTHONPATH,这种设置方法永久有效。

性能优化

  1. 优化算法时间复杂度
  2. 减少冗余数据
  3. 合理使用 copy 和 deepcopy
  4. 使用 dict 或 set 查找元素
  5. 合理使用生成器 和 yield
  6. 优化循环,尽量减少循环内事务
  7. 优化包含多个表达式的顺序
  8. 使用join合并迭代器中的字符串
  9. 选择合适的格式化字符方式
  10. 不借助中间变量交换两个变量的值
  11. 尽量使用if is
  12. 尽量使用级联比较 x<y<z
  13. 使用 while 1 替换 while True
  14. 使用 ** 而不是 Pow
  15. 尽量使用 C 实现相同功能的包
  16. 使用最佳的反序列换方式
  17. 使用 C 扩展
  18. 并行编程
  19. 使用加速解释器
  20. 使用性能分析工具
  21. 使用Taichi

猴子补丁

猴子补丁(Monkey Patch)的名声不太好,因为它会在运行时动态修改模块、类或函数,通常是添加功能或修正缺陷。

# 定义一个Dog类
class Dog:
    def eat(self):
        print("A dog is eating ...")


# 在类的外部给 Dog 类添加猴子补丁
def walk(self):
    print("A dog is walking ...")


Dog.walk = walk

# 调用方式与类的内部定义的属性和方法一样
dog = Dog()
dog.eat()
dog.walk()