本文由xgfone
整理、写作而成,如有网络转载或用于商业,请注明以下版权声明:
Copyright © 2012-2016 xgfone(三界). All Rights Reserved.
本文并不打算写成一个Python入门教材,至少目前是这样;本文主要提炼Python语法要点,讲解一些比较难以理解的部分,作为一个入门者的提高,以帮助一些已入门者迅速理解、掌握Python语言精髓。因此,要想理解本文内容,需要有Python基础知识,可以参阅Python官方手册的快速入门教程,也可以看其他的入门教材,这里特别推荐Vamei的“Python快速教程”。
本文没有讲解基础语法,比如Python字面值、表达式、语句、如何定义一个函数或类、如何调用一个函数以及如何使用类对象,但本文详细提炼了部分重点语法、讲解了一些难点和高级语法,如yield语法、装饰器、属性管理、元类等等,已入门者可以把它作为一个手册。本文参考了《Python学习手册(第四版)》(中文版)(下文简称为《学四》)和Python的官方手册。
如果没有特殊说明,本文所讲的语法、知识都是基于Python官方的实现——C实现,即CPython
;而且,如果没有特殊说明,本文基于的Python版本默认为3.X
。
Python 是动态的强类型语言;Python 的类型系统属于 Duck(鸭子)类型。
简单地说,声明或定义一个变量或对象时,如果不需要指定类型,而是由语言动态判断,则该语言为动态类型语言;否则为静态类型语言。 比如:Python
、Ruby
、JavaScript
等是动态类型语言,C/C++
、Java
、C#
、Go
等是静态类型语言。
简单地说,当一个变量或对象的属性没有定义时,如果解析器或编译器不判断为错误,而是给出一个默认值,那么该语言为弱类型语言;否则为强类型语言。比如:JavaScript
、Shell
为弱类型语言,C/C++
、Java
、C#
、Python
、Go
等为强类型语言。
简单地说,Duck 类型就是:一个对象有效的语义,不是由继承自指定的类(通过类继承)或实现特定的接口(如 Java 中 interface),而是由该对象的当前方法和属性的集合来决定;在 Duck 类型中,关注的并不是对象的类型本身,而是该对象是如何使用
。
比如:在 Python 中,定义了一个类型 A 以及它的一个实例 a,类型 A 及其父类中并没有定义方法 print()
,但并不代表实例 a 不能调用它;在 Duck 类型中,可以在类型 A 定义外向它的方法方法和属性集合中添加一个方法 print()
,此时就可以调用 print()
了,如:
class A: pass
a = A()
a.printf = lambda: "hello" # 向实例 a 的方法和属性集体中添加一个方法 printf
print a.printf() # 打印字符串 "hello" 到终端上
A.pp = lambda self: "hello" # 向类型 A 的方法和属性集体中添加一个方法 pp
print a.pp() # 打印字符串 "hello" 到终端上
细心的读者可能发现:
(1)为实例 a 添加方法时,lambda 表达式没有指定参数,而为类型 A 添加方法时,lambda 表达式却指定了参数;
(2)为类型 A 添加了方法但没有为实例 a 添加该方法,而实例 a 却能调用该方法。
关于第一个问题,请参见下文第五大节中的第 17 小节
——方法的调用;简单地说,这是关于名字绑定(Name Binding)以及方法调用的问题。关于第二个问题,这实例属性名或方法名查找的问题,请参见下文第五大节中的第 15 小节
和第六大节中关于”作用域与命名空间“的第 9 小节
。