您的位置:首页 - 教程 - python - 正文
初识Python全面概述

学习一门语言时,总有一些内容是需要在开始时强制记住的,否则后面的内容无法进行。这节我们就先来说一些在学习Python前需要了解的内容。

本节内容


  1. 开发工具的选择
  2. Hello, World!
  3. Python2.x or Python3.x
  4. 变量与常量
  5. 接收用户输入
  6. 指定字符编码与解释器
  7. 注释
  8. 导入模块
  9. 获取脚本传入的参数
  10. 代码块语法
  11. Python程序执行过程与.pyc文件

一、开发工具的选择


古人云“工欲善其事,必先利其器”,选择一个合适的开发工具,可以帮助我们提高工作效率。通常有以下几种工具可以选择:

  • 纯文件工具:没有任何提示,完全需要手动写代码,编译和运行也需要手动完成,如 记事本;
  • 简单GUI开发工具:有简单的提示,但是编译和运行还是需要手动完成,如 notepad++;
  • 高级GUI工具:有提示,且编译和运行过程由开发工具自动完成,如 eclipse、Pycharm

有些人认为刚开始学习一门编程语言时,应该使用记事本或notepad++这样简单的工具,减少对高级GUI开发工具的依赖,这样可以更清楚的明白被开发工具屏蔽掉的语言底层的运行过程和原理。但是这个还是看个人吧,比如我觉得一个新手刚开始就使用没有任何提示的开发工具会降低练习的效率,甚至会进一步打击自信心和学习动力。如果一开始就对它新生畏惧,那将来是很难把它学好的。

当然如何选择还是由看官自己决定,这里推荐的开发python的GUI工具是Pycharm,理由如下:

  • 跨平台,基本上现在常用的桌面操作系统多有对应的版本可以下载
  • 分为社区版和商用版,社区版免费使用,但是功能会少一些(对于新手完全够用);商业版功能全面,但是需要付费。

二、Hello, World


在任意一个目录下创建一个hello.py文件,我们来输出一个经典语句"Hello World!"

print("Hello, World")

执行hello.py这个python脚本的方式是:

python hello.py

输出为:

Hello, World

当然也可以直接进入python解释器交互式终端去执行print("Hello, World"),如下图所示:

思考:为什么打印一句“Hello World”已经成为很多人学习一门新语言的第一句代码?

有人说,这是学习一门语言入门的象征,因为写完了这个我就可以对别人说“我会写xx语言的程序了”。本人认为要理解为什么Hello World如此简单,却又如此广为人知并被传颂,只需要想清楚一个问题:这个程序带给我们什么?

  1. 它告诉我们在这个编程语言中基本的输出语句是怎样的,这很重要;

  2. 它告诉我们要怎样去执行这个编程语言编写的程序,这同样很重要。

如果不知道上述两个问题,我们将寸步难行。

三、Python 2.x or Python 3.x


1. Python 2.x 与 Python 3.x之间的关系

我们分别使用Python2.7 和 Python3.5的解释器提供的交互式终端来分别执行以下两条指令:

print("Hello, World")
print "Hello, World"

通过上图的执行结果会发现,print "Hello, World" 这条语句在Python2.7中可以正常执行,而在Python 3.5中会报错,也就是说Python 3.x与Python 2.x是不兼容的。这貌似是Python开发者犯的一个错误,而事实是Guido Van Rossum(Python语言的最初创建者)故意为之。Guido的本意就是想不考虑太多向后兼容性的问题,去适当地清理一下Python 2.x中不合理的内容,而不是把Python 3.x简单的当做对Python 2.x的更新版本。

实际上,Python 3.0在2008年12月就已经发布了,Python官方在2010年年中发布2.7时宣布,2.7将是Python 2.x的最后一个主发布版本。其实Python 2.7 是向Python 3.x的一个过渡版本,里面支持了一些Python 3.x的特性

2014年11月,Python官方宣布Python 2.7将会被支持到2020年,并再次确认了不会有Python 2.8发布,希望用户尽快迁移到Python 3.4+ 。3.x正在处于积极开发状态,并且在过去5年里已经发布了多个稳定版本,包括2012年的3.3,2014年的3.4,2015年的3.5。这意味着最近所有的标准库更新将默认只能在Python 3.x中可用。

2. Python 2.x 与 Python 3.x 的主要区别:

在Python 3.x中,输出语句需要使用print()函数,该函数接收一个关键字参数,以此来代替Python 2.x中的大部分特殊语法。下面是几个对比项:

目标 Python 2.x的实现 Python 3.x的实现
拼接并输出多个值 print "The result is", 2+3 print("The result is", 2+3)
打印一个元祖(1,2,3) print(1,2,3) 或 print (1,2,3) print((1,2,3))
输出一个内容并且不换行 print “Hello”, print("Hello", end=" ")
输出一个新空白行 print print()
将输出内容输出到标准错误输出文件 print >>sys.stderr, "fatal error" print("fatal error", file=sys.stderr)
自定义多个输出内容之间的分隔/拼接符 N/A print("There are <", 2**32, "> possibilites!", sep="")

2) ALL IS UNICODE

Python 2.x中使用的默认字符编码为ASCII码,要使用中文字符的话需要指定使用的字符编码,如UTF-8;Python 3.x中使用的默认字符编码为Unicode,就不存在这个问题了。

3) 多变量同时赋值问题

python 2.x中如果要给多个变量同时赋值,要求=号右边的表达式返回结果的个数要与=号左边接收值的变量个数相等,不能多,也不能少。如:

a,b,c = (1,2,3) # 正常,a=1, b=2, c=3
a,b,c = range(5) # 报错,ValueError: too many values to unpack
a,b,c,d,e = [1,2,3] # 报错,ValueError: need more than 3 values to unpack 

python 3.x中允许=号昨边的变量数小于=号右边表达式返回的结果的个数,但是需要有1个且只能有1个字典类型的变量来接收多余的返回值。与python 2.x相同的是 python 3.x中=号左边的变量数也是不能多与=号右边表达式的返回值个数,但是错误提示语更清晰了。

a,b,c = (1,2,3) # 正常,a=1, b=2, c=3
a,*b,c = range(5) # 正常,a=0, b=[1,2,3], c=4
a,b,c,d,e = [1,2,3] # 报错,ValueError: not enough values to unpack (expected 5, got 3)

4) 某些库改名字了

Old Name New Name
_winreg winreg
ConfigParser configparser
copy_reg copyreg
Queue queue
SocketServer socketserver
markupbase _markupbase
repr reprlib
test.test_support test.support

5) 选择Python 2 还是 Python 3呢?

如果是要开发一个新项目,不用考虑与老项目的兼容问题,最好是使用Python 3,因为就像Python官方说的那样,Python 3才是Python语言的将来。现在很多第三方类库已经完成了或者正在积极完成对Python 3的支持,只是有些项目由于过于庞大,很难在短时间内完成。我们需要考虑的最大问题在于,新项目中是否存在必须的第三方类库,且该类库当前还不支持Python 3。如果不存在这个问题,那坚定的选择Python 3吧。

四、变量与常量


1. 变量

这是只是简单说下Python中变量的定义和使用,方便继续下面的内容。事实上,Python中变量的使用确实很简单:

name = "wader"
age =28
print("Name: ", name,) # Name: wader
print("Age : ", age) # Age : 28

2. 查看变量数据类型

python定义变量无需指定变量类型,python解释器会在运行时自动推断变量的数据类型。我们可以通过type()方法来查看变量类型:

type(name) # str
type(age) # int

3. 常量

事实上,Python中没有语法约束下的常量,仅仅是用完全大写字母的变量来表示这个变量不应该被改变。

COUNT = 10

五、接收用户输入


很多时候都需要与用户进行交互,通过用户输入的内容来做下一步操作。这里需要说明的是,Python 2 与Python 3中接收用户输入的方法是不一样的。

1. Python 2

Python 2中接收用户输入时,主要使用的是raw_input()函数:

name = raw_input("Enter your name: ")
print "Your name is ", name

2. Python 3

Python 3中接收用户输入时,主要使用的是input()函数:

name = input("Enter your name: ")
print("Your name is ", name)

3. 说明

  • 通过Python 2中的raw_input() 与 Python 3中的input() 获取到的值都是str类型,若想转换为其他数据类型需要进行强制类型转换,这个等将Python数据类型的时候会说。

  • Python 2中其实也有input()方法,但是通过这个input()方法获取的值是与输入内容的数据类型有关的,这很容易造成混乱,因此现在Python 2中很少用这个方法,而是用raw_input()代替了。

六、 指定字符编码与解释器


1. 字符编码的作用

计算机只认识0和1组成的二进制序列,因此任何文件中的内容要想被计算机识别或者想存储在计算机上都需要转换为二进制序列。那么字符与二进制序列怎么进行想换转换呢?于是人们尝试建立一个表格来存储一个字符与一个二进制序列的对应关系

  • 编码 将字符转换为对应的二进制序列的过程叫做字符编码
  • 解码 将二进制序列转换为对应的字符的过程叫做字符解码

2. 字符编码的简单发展过程

1) ASCII码诞生

最早建立这个字符与十进制数字对应的关系的是美国,这张表被称为ASCII码(American Standard Code for Information Interface, 美国标准信息交换代码)。ASCII码是基于拉丁字母的一套电脑编程系统,主要用于显示现代英语和其他西欧语言。它被设计为用1个字节来表示一个字符,所以ASCII码表最多只能表示2**8=256个字符。实际上ASCII码表中只有128个字符,剩余的128个字符是预留扩展用的。

2) GBK等各国编码诞生

随着计算机的普及和发展,很过国家都开始使用计算机。大家发现ASCII码预留的128个位置根本无法存储自己国家的文字和字符,因此各个国家开始制定各自的字符编码表,其中中国的的字符编码表有GB2312和GBK。

3) Unicode诞生

后来随着世界互联网的形成和发展,各国的人们开始有了互相交流的需要。但是这个时候就存在一个问题,每个国家所使用的字符编码表都是不同的。比如我们发送一句“你好,我好喜欢你演的爱情动作电影!”给岛国的仓老师,苍老师电脑上用的是日本的字符编码表,因此她的电脑无法正确显示我们发送的内容。这个时候,人们希望有一个世界统一的字符编码表来存放所有国家所使用的文字和符号,这就是Unicode。Unicode又被称为 统一码、万国码、单一码,它是为了解决传统的字符编码方案的局限性而产生的,它为每种语言中的每个字符设定了统一并且为之一的二进制编码。Unicode规定所有的字符和符号最少由2个字节(16位)来表示,所以Unicode码可以表示的最少字符个数为2**16=65536。

4) UTF-8诞生

为什么已经有了Unicode还要UTF-8呢?这是由于当时存储设备是非常昂贵的,而Unicode中规定所有字符最少要由2个字节表示。人们认为像原来ASCII码中的字符用1个字节就可以了,因此人们决定创建一个新的字符编码来节省存储空间。UTF-8是对Unicode编码的压缩和优化,它不在要求最少使用2个字节,而是将所有字符和符号进行分类:

  • ascii码中的内容用1个字节保存
  • 欧洲的字符用2个字节保存
  • 东亚的字符用3个字节保存
  • ...

UTF-8是目前最常用,也是被推荐使用的字符编码。

3. Python中的字符编码问题

我们上面提到过,一般在两个地方会用到字符编码:

  • 磁盘写入或读取数据时;
  • 程序执行时的输入和输出;

磁盘写入或读取数据时使用的字符编码是由编辑器指定的工程或文件的字符编码决定的,这与Python解释器是无关的;但是Python程序执行时,将Python脚本文件加载到内存时所使用的字符编码是主要问题所在。在Python 2中,Python解释器默认使用的是ASCII码,此时如果要运行的程序中如果有中文Python解释器就会报错。

print("你好,世界")

SyntaxError: Non-ASCII character '\xe4' in file C:/Users/wader/PycharmProjects/LearnPython/day01/code.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

这是因为Python解释器执行该程序时试图从ASCII编码表中查找中文字符对应的二进制序列,但是发现找不到。此时要想该程序正常运行,就需要在python脚本文件的开始位置声明该文件的所使用的字符编码:

# -*- coding:utf-8 -*-

print("你好,世界")

需要说明的是

Python 3的解释器默认使用Unicode编码,它本身是可以对中文字符进行编码和解码的,所以即便不指定字符编码也能正常运行,但是还是建议保留字符编码的声明。

4. 指定python解释器

通常python脚本都是跑在Linux上的,为了让python脚本文件可以像shell脚本那样可以直接调用执行,我们通常需要在python文件最开始的位置指定python解释器:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

print("你好,世界")

不建议写python解释器的绝对路径,如:

#!/usr/bin/python
# -*- coding:utf-8 -*-

print("你好,世界")

因为这样写的话,将来要想更换python解释器是非常麻烦的。

七、注释


1. 单行注释

单行注释:# 注释

如果注释与代码不在同一行,通常注释位于代码的上面一行,且#号与注释内容之间至少要有一个空格。

#!/usr/bin/python
# -*- coding:utf-8 -*-

# 这是单行注释
print("你好,世界")

如果注释与代码在同一行,注释要写在代码的后面,且代码与#号之间至少要有2个空格,同时#号与注释内容之间至少要有1个空格。

#!/usr/bin/python
# -*- coding:utf-8 -*-

print("你好,世界")  # 这是单行注释

2. 多行注释

多行注释的内容要用3个引号包起来,可以用单引号,也可以用双引号。

#!/usr/bin/python
# -*- coding:utf-8 -*-

""" 
这是多行注释
这是多行注释
这是多行注释
"""
print("你好,世界")

八、导入模块


当Python内置的核心模块提供的功能无法满足我们的需求时就需要导入外部模块,而导入模块的功能有两种方式:

  • import MODULE :导入整个模块
  • from MODULE import XX :导入模块中的一部分(方法、变量、或常量等)

例如,要想查看或更改python查找模块的路径列表就需要使用sys模块下的path变量;若需要执行系统命令可以使用os模块下的system()方法。

import sys
from os import system

print(sys.path)
print(system("ping hovertree.com"))

九、获取python脚本执行时传入的参数


我们在写shell脚本时,经常会通过接受执行脚本时传入的变量来做相应的操作,来保证脚本的灵活性。比如我们要写一个脚本来调用ping命令对指定的域名进行ping测试,这时候显然将域名当做参数传递给脚本要比把域名写死在脚本中灵活的多。shell中可以只用$1,$2这样的特殊变量来获取传入的参数,而python中需要用sys模块下的argv变量来获取。

sys.argv是一个列表,与shell相同,其第一个元素是当前脚本的名称,之后才是传入的参数。

编写一个ping.py,内容如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import sys
import os

print(type(sys.argv))
print(sys.argv)

执行该脚本,结果如下图所示:

十、代码块


在Java和C语言中用花括号{}包起来的部分就是一个代码块,shell脚本中的代码块是由专门的开始和结束标识的,而python中的代码块是靠“缩进对齐”来表示的。下面我们分别一个if-else的条件判断来对这几个语言的代码块表示方式做一个对比:

1. Java

...
int a = 3;
int b = 5;
int big_num;

if(a > b){
    big_num = a;
}else{
    big_num = b;
}

System.out.println(big_num)
...

2. Shell

declare -i a=3
declare -i b=5
declare -i big_num

if [ $a -gt $b ];then
    big_num=$a
else
    big_num=$b
fi

echo $big_num

3. Python

a = 3
b = 5

if a > b:
    big_num = a
else:
    big_num = b

print(big_num)

十一、Python的执行过程与.pyc文件


在之前的文章我们已经解释过:Python是一个动态的、强类型的、解释型的编程语言。而实际上,解释型语言与编译型语言的界限正在变得模糊。包括Python在内的很多高级编程语言,会将源代码先编译成特定类型的中间代码,然后再由解释器去执行,这样可以提高执行效率。Python的解释器同时也是生成Python中间代码的编译器,.pyc文件就是存放Python中间代码的文件。执行Python代码时,如果该源码文件导入了其他的.py文件,那么执行过程中会自动生成一个与导入的.py文件同名的.pyc文件。


评论: