第二章

Python 解释器


Python是解释性语言。Python解释器同一时间只能运行一个程序的一条语句。标准的交互Python解释器可以在命令行中通过键入python命令打开:

1
2
3
4
5
6
C:/Users/86178>python
Python 3.9.15 (main, Nov 24 2022, 14:39:17) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 5
>>> print(a)
5

>>>提示输入代码。要退出Python解释器返回终端,可以输入exit()或按Ctrl-D。

运行Python程序只需调用Python的同时,使用一个.py文件作为它的第一个参数。假设创建了一个hello_world.py文件,它的内容是:

1
print('Hello world')

你可以用下面的命令运行它(hello_world.py文件必须位于终端的工作目录):

1
2
$ python hello_world.py
Hello world

IPython基础


运行Jupyter Notebook

notebook是Jupyter项目的重要组件之一,它是一个代码、文本(有标记或无标记)、数据可视化或其它输出的交互式文档。Jupyter Notebook需要与内核互动,内核是Jupyter与其它编程语言的交互编程协议。Python的Jupyter内核是使用IPython。要启动Jupyter,在命令行中输入jupyter notebook:

在多数平台上,Jupyter会自动打开默认的浏览器(除非指定了--no-browser)。或者,可以在启动notebook之后,手动打开网页http://localhost:8888/

当保存notebook时(File目录下的Save and Checkpoint),会创建一个后缀名为.ipynb的文件。这是一个自包含文件格式,包含当前笔记本中的所有内容(包括所有已评估的代码输出)。可以被其它Jupyter用户加载和编辑。要加载存在的notebook,把它放到启动notebook进程的相同目录内。

Tab补全

在shell中输入表达式,按下Tab,可以补全:

  • 已输入变量(对象、函数等等)的命名空间

  • 任何对象的方法和属性

  • 模块名

  • 文件路径时(即使是Python字符串)

自省

在变量前后使用问号?,可以:

  • 显示对象的信息

  • 对象是一个函数或实例方法,定义过的文档字符串,也会显示出信息

  • 使用??会显示函数的源码

  • 搜索IPython的命名空间,字符与通配符结合可以匹配所有的名字

%run命令

你可以用%run命令运行所有的Python程序。

如果一个Python脚本需要命令行参数(在sys.argv中查找),可以在文件路径之后传递,就像在命令行上运行一样。

笔记:如果想让一个脚本访问IPython已经定义过的变量,可以使用%run -i

在Jupyter notebook中,可以使用%load,它将脚本导入到一个代码格中。

中断运行的代码

代码运行时按Ctrl-C,无论是%run或长时间运行命令,都会导致KeyboardInterrupt。这会导致几乎所有Python程序立即停止,除非一些特殊情况。

警告:当Python代码调用了一些编译的扩展模块,按Ctrl-C不一定将执行的程序立即停止。在这种情况下,你必须等待,直到控制返回Python解释器,或者在更糟糕的情况下强制终止Python进程。

从剪贴板执行程序

使用Jupyter notebook,可以将代码复制粘贴到任意代码格执行。

使用%paste%cpaste函数。

%paste可以直接运行剪贴板中的代码:

%cpaste功能类似,但会给出一条提示:

1
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.

使用%cpaste,你可以粘贴任意多的代码再运行。你可能想在运行前,先看看代码。如果粘贴了错误的代码,可以用Ctrl-C中断。

键盘快捷键

Jupyter notebooks有另外一套庞大的快捷键,建议参阅Jupyter notebook的帮助文档。

魔术命令

IPython中特殊的命令(Python中没有)被称作“魔术”命令。这些命令可以使普通任务更便捷,更容易控制IPython系统。魔术命令是在指令前添加百分号%前缀。

魔术命令可以被看做IPython中运行的命令行。许多魔术命令有“命令行”选项,可以通过?查看

魔术函数默认可以不用百分号,只要没有变量和函数名相同。这个特点被称为“自动魔术”,可以用%automagic打开或关闭。

一些魔术函数与Python函数很像,它的结果可以赋值给一个变量。

IPython的文档可以在shell中打开,我建议你用%quickref%magic学习下所有特殊命令。

一些可以提高生产率的交互计算和Python开发的IPython指令。

表2-2 一些常用的IPython魔术命令

集成Matplotlib

IPython非常好的集成了数据可视化和其它用户界面库,比如matplotlib。%matplotlib魔术函数配置了Jupyter notebook中的matplotlib。这点很重要,其它创建的图不会出现(notebook)或获取session的控制,直到结束(shell)。

Python 语法基础


本节将会概述基本的 Python 概念和语言机制。

缩进,代码块和语句的结束

Python 使用缩进(tab和空格)来组织代码,而不是像其他语言,比如R,C++,Java等一样使用括号来实现。

Python 中的冒号标志着缩进代码块的开始,冒号之后的所有代码的缩进量必须相同。

Python 的语句不需要使用分号结尾,但是分号可以对同在一行的语句进行切分。

1
a = 1; b = 2; c = 3

Python不建议将多条语句放到一行,这会降低代码的可读性。

万物皆对象

就像Java一样(笔者学过一段时间Java),我们可以把任何事物看成一个对象,这个对象中包含着一些属性和一些方法。

值得注意的是,python的对象模型具有一致性,每个数字、字符串、数据结构、函数、类、模块等,都是在Python解释器的自有“盒子”内,它被认为是Python对象。

注释

任何前面带有 # 的文本都会被Python解释器忽略。

1
2
# Hello World!
Hello Python! # 放在代码之后,可用来说明该语句的作用

函数和对象方法调用

在调用函数时,我们使用圆括号 ( ),传递0个或者多个参数,并且可以使用一个变量来接受函数调用的返回值。

1
2
test = f(x, y, z)
g()

几乎Python中的每个对象都有附加的函数,称作 方法,可以用来访问对象的内容。
想了解的话建议参考python官方教程

函数可以使用位置和关键词参数:

1
test = f(a, b, c, d = 1, e = 'example')

后面会有更多介绍。

变量和参数传递

当在Python中创建变量(或名字),你就在等号右边创建了一个对这个变量的引用。
有其他编程语言基础的话应该能理解这个引用是什么意思,就像C语言里面的指针一样,我假定大家是有一定基础的,所有在这里就不再多说了。不懂的建议参考菜鸟编程

Python被认为是强类型化语言,这意味着每个对象都有明确的类型(或类),默认转换只会发生在特定情况下。

为了让函数可以处理多种类型的输入,我们可以使用isinstance函数检查对象的数据类型。

属性和方法

Python的对象通常都有属性和方法。

鸭子类型

通常,我们可能不关心对象的类型,只关心对象是否有某些方法或用途。这通常被称为“鸭子类型”,来自“走起来像鸭子、叫起来像鸭子,那么它就是鸭子”的说法。

引入

在Python中,模块就是一个有.py扩展名、包含Python代码的文件。

1
2
import numpy as np
import pandas as pd

二元运算符和比较运算符

二元运算符

可变与不可变对象

Python中的大多数对象,比如列表、字典、Numpy数组,和类,都是可变的,即这些对象或者这些对象包含的值可以被修改。

而其他的,例如 字符串和元组,是不可变的。

标量类型

Python的标准库中有一些内建的类型,用于处理数值数据、字符串、布尔值,和日期时间。这些单值类型被称为标量类型,本系列文章中称其为标量。

数值类型

Python的主要数值类型是intfloat

字符串

Python拥有强大的处理字符串的功能。(这部分内容很简单,以后会从实际应用中讲述,可自行了解)

字节和Unicode

在Python 3及以上版本中,Unicode是一级的字符串类型,这样可以更一致的处理ASCII和Non-ASCII文本。

布尔值

True and False

类型转换

str、bool、int和float也是函数,可以用来转换类型。

None

None是Python的空值类型,如果一个函数没有明确的返回值,就会默认返回None。

另外,None不仅是一个保留字,还是唯一的NoneType的实例。

日期和时间

Python内建的datetime模块提供了datetimedatetime类型。datetime类型结合了datetime,是最常使用的。

strftime方法可以将datetime格式化为字符串:

1
2
In [108]: dt.strftime('%m/%d/%Y %H:%M')
Out[108]: '10/29/2011 20:30'

strptime可以将字符串转换成datetime对象:
1
2
In [109]: datetime.strptime('20091031', '%Y%m%d')
Out[109]: datetime.datetime(2009, 10, 31, 0, 0)

控制流

if、elif、else

if是最广为人知的控制流语句。它检查一个条件,如果为True,就执行后面的语句。

if后面可以跟一个或多个elif,所有条件都是False时,还可以添加一个else

如果某个条件为True,后面的elif就不会被执行。当使用andor时,复合条件语句是从左到右执行。

for 循环

for循环是在一个集合(列表或元组)中进行迭代,或者就是一个迭代器。

你可以用continue使for循环提前,跳过剩下的部分。

可以用break跳出for循环,break只中断for循环的最内层,其余的for循环仍会运行。

While 循环

while循环指定了条件和代码,当条件为False或用break退出循环。

pass

pass是Python中的非操作语句。代码块不需要任何动作时可以使用(作为未执行代码的占位符);因为Python需要使用空白字符划定代码块,所以需要pass

range

range函数返回一个迭代器,它产生一个均匀分布的整数序列。

三元表达式

Python中的三元表达式可以将if-else语句放到一行里。语法如下:

1
value = true-expr if condition else false-expr

因此,三元表达式中的if和else可以包含大量的计算,但只有True的分支会被执行。因此,三元表达式中的if和else可以包含大量的计算,但只有True的分支会被执行。

虽然使用三元表达式可以压缩代码,但会降低代码可读性。