python介绍与安装(二)
4 Python基础语法
Python 语言与 Perl,C 和 Java 等语言有许多相似之处。但是,也存在一些差异。
4.1 第一个python程序
交互式编程
交互式编程不需要创建脚本文件,是通过Python解释器的交互模式进行编写代码。
linux上:
Windows上
脚本式编程
通过脚本参数调运解释器开始执行脚本,知道脚本执行机完毕。当脚本执行完成后,解释器不在有效。
[root@bogon test]# cat hw.py #/usr/bin/python3 #-*-coding:utf-8 -*- print("您好,世界!!!") [root@bogon test]# [root@bogon test]# python3 hw.py 您好,世界!!!
4.2 标识符
在 Python 里,标识符由字母、数字、下划线组成。
在 Python 中,所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。
Python 中的标识符是区分大小写的。
以下划线开头的标识符是有特殊意义的。以单下划线开头 _foo 的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用 from xxx import * 而导入。
以双下划线开头的 __foo 代表类的私有成员,以双下划线开头和结尾的 foo 代表 Python 里特殊方法专用的标识,如 init() 代表类的构造函数。
Python 可以同一行显示多条语句,方法是用分号 ; 分开,如:
a = "anliu" ;print(a) anliu
4.3 保留字符
下面的列表显示了在Python中的保留字。这些保留字不能用作常数或变数,或任何其他标识符名称。
所有 Python 的关键字只包含小写字母。
4.4 行与缩进
学习 Python 与其他语言最大的区别就是,Python 的代码块不使用大括号 {} 来控制类,函数以及其他逻辑判断。python 最具特色的就是用缩进来写模块。缩进的空白数量是可变的,但是所有代码块语句必须包含相同的缩进空白数量,这个必须严格执行。
- IndentationError: unindent does not match any outer indentation level**错误表明,你使用的缩进方式不一致,有的是 tab 键缩进,有的是空格缩进,改为一致即可。
- 如果是 **IndentationError: unexpected indent** 错误, 则 python 编译器是在告诉你"**Hi,老兄,你的文件里格式不对了,可能是tab和空格没对齐的问题**",所有 python 对格式要求非常严格。
建议你在每个缩进层次使用 单个制表符 或 两个空格 或 四个空格 , 切记不能混用
4.4 多行语句
Python语句中一般以新行作为语句的结束符。
但是我们可以使用斜杠( \)将一行的语句分为多行显示,如下所示:
#!/bin/evn python
#-*- coding:utf-8 -*-
#Author:Anliu
item_one = 1
item_two = 2
item_three = 3
total = item_one + \
item_two + \
item_three
print(total)
语句中包含 [], {} 或 () 括号就不需要使用多行连接符。如下实例:
#!/bin/evn python #-*- coding:utf-8 -*- #Author:Anliu dict = {"shangluo":"shanxi", "yuncheng":"shanxi", "zhumadian":"henan" } print(dict)
4.5 引号
Python 可以使用引号( ' )、双引号( " )、三引号( ''' 或 """ ) 来表示字符串,引号的开始与结束必须的相同类型的。
其中三引号可以由多行组成,编写多行文本的快捷语法,常用于文档字符串,在文件的特定地点,被当做注释。
4.6 注释
python中单行注释采用 # 开头。注释可以在语句或表达式行末:
#!/bin/evn python #-*- coding:utf-8 -*- #Author:Anliu # 第一个注释 print("Hello, Python!") # 第二个注释
#!/bin/evn python #-*- coding:utf-8 -*- #Author:Anliu # 第一个注释 print("Hello, Python!") # 第二个注释 ''' 这是什么鬼 这到底是什么鬼 '''
4.7 空行
函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。
空行与代码缩进不同,空行并不是Python语法的一部分。书写时不插入空行,Python解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。
记住:空行也是程序代码的一部分。
4.8 用户交互
下面的程序执行后就会等待用户输入,按回车键后就会退出:
#!/bin/evn python
#-*- coding:utf-8 -*-
#Author:Anliu
input("please input you name:\n" )
以上代码中 ,\n 实现换行。一旦用户按下 enter(回车) 键退出,其它键显示。
4.9 输出
print 默认输出是换行的,如果要实现不换行需要在变量末尾加上逗号 ,
#!/bin/evn python #-*- coding:utf-8 -*- #Author:Anliu x = "a" y = "b" print(x) print(y) print("_____") print("the number is a:",x,y)
实例:格式化输出的三种模式
用户交互,提示用户输入host,hostname,ip,NS信息,并将输入结果格式化输出如下:
方法一:字符串拼接
#!/usr/bin/env python #-*- coding:utf-8 -*- #AUTHOR: Carve hosts = input("please input your hosts:") hostname = input("please input your hostname:") ip = input("please input your ipaddr:") ns = input("please input your NS:") #print(hosts,hostname,ip,ns) info = '''--------------host: '''+ hosts + ''' ------------------- host: ''' + hosts + ''' hostname: ''' + hostname + ''' ip: ''' + ip + ''' ns: '''+ ns + ''' ''' print(info)
方法二:带格式输出
#!/usr/bin/env python #-*- coding:utf-8 -*- #AUTHOR: Carve hosts = input("please input your hosts:") hostname = input("please input your hostname:") ip = input("please input your ipaddr:") ns = input("please input your NS:") #print(hosts,hostname,ip,ns) info = ''' --------------info of %s ------------------- host: %s hostname: %s ip: %s ns: %s ''' %(hosts,hosts,hostname,ip,ns) print(info)
方法三:format函数变量映射
#!/usr/bin/env python #-*- coding:utf-8 -*- #AUTHOR: Carve hosts = input("please input your hosts:") hostname = input("please input your hostname:") ip = input("please input your ipaddr:") ns = input("please input your NS:") #print(hosts,hostname,ip,ns) info = ''' --------------info of {_host} ------------------- host: {_host} hostname: {_hostname} ip: {_ip} ns: {_ns} ''' .format(_host = hosts, _hostname = hostname, _ip = ip, _ns = ns ) print(info)
方法四:format函数顺序映射
#!/usr/bin/env python #-*- coding:utf-8 -*- #AUTHOR: Carve hosts = input("please input your hosts:") hostname = input("please input your hostname:") ip = input("please input your ipaddr:") ns = input("please input your NS:") #print(hosts,hostname,ip,ns) info = ''' --------------info of {0} ------------------- host: {0} hostname: {1} ip: {2} ns: {3} ''' .format(hosts,hostname,ip,ns) print(info)
4.10 模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块让你能够有逻辑地组织你的 Python 代码段。
把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
模块能定义函数,类和变量,模块里也能包含可执行的代码。
例子
下例是个简单的模块 support.py:
support.py 模块:
#Author:Anliu def print_func( par ): print("Hello:", par) return
4.10.1 import 语句
模块的引入
模块定义好后,我们可以使用 import 语句来引入模块,语法如下:
import module1[, module2[,... moduleN]]
比如要引用模块 math,就可以在文件最开始的地方用 import math 来引入。在调用 math 模块中的函数时,必须这样引用:
模块名.函数名
当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support.py,需要把命令放在脚本的顶端:
#Author:Anliu # 导入模块 import support # 现在可以调用模块里包含的函数了 support.print_func("Runoob")
一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。
4.10.2 from…import 语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块 fib 的 fibonacci 函数,使用如下语句:
from fib import fibonacci
这个声明不会把整个 fib 模块导入到当前的命名空间中,它只会将 fib 里的 fibonacci 单个引入到执行这个声明的模块的全局符号表。
4.10.3 from…import* 语句
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:
from modname import *
这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
例如我们想一次性引入 math 模块中所有的东西,语句如下:
from math import *
4.10.4 搜索路径
当你导入一个模块,Python 解析器对模块位置的搜索顺序是:
1、当前目录
2、如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
3、如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。
模块搜索路径存储在 system 模块的 sys.path 变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
PYTHONPATH 变量
作为环境变量,PYTHONPATH 由装在一个列表里的许多目录组成。PYTHONPATH 的语法和 shell 变量 PATH 的一样。
在 Windows 系统,典型的 PYTHONPATH 如下:
set PYTHONPATH=c:\python27\lib;
在 UNIX 系统,典型的 PYTHONPATH 如下:
set PYTHONPATH=/usr/local/lib/python
4.10.5 模块例举
Python的强大之处就是在于他有非常丰富和强大的标准库和第三方库,几乎你想实现的任何功能都有相应的Python库支持。
模块加载时,回根据环境路径去查找模块。
默认的第三方库在
E:\Python3\Lib\site-packages
现在简单介绍以下两个模块:
#Author:Anliu import sys
print(sys.path) print(sys.argv)
os.system不保存打印结果
#Author:Anliu import os cmd_res = os.system("dir") print("----->",cmd_res)
os.popen将打印结果保存
#Author:Anliu import os #cmd_res = os.system("dir") #执行命令不保存结果 #print("----->",cmd_res) cmd_res = os.popen("dir").read() print("------->",cmd_res)
模块的导入,首先当前目录下查找文件,查找不到再到系统定义的路径下去查找.
OS模块可以再我们的标准库中找到,而sys模块是在标准库中找不到的,因为python中sys模块是写到python解释器里面的。所以我们说模块不仅仅是用户定义或者标准库第三方库提供,python解释器本身也提供。
4.11 .pyc
pyc设什么东西?
我们知道python是一门解释性语言,但是在执行之后,会产生一个.pyc的文件,例如:
如果是解释性语言,那么生成的.pyc是干什么的呢?c应该是compiled的缩写才对。
4.11.1 解释型语言和编译型语言
计算机是不能够识别高级语言的,所以当我们运行一个高级语言编程的时候,就需要一个“翻译机”来从事把高级语言变成计算机能读懂的机器语言。这个过程分为两类:一种是编译,一种是解释。
编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转换为机器语言。运行时就不需要翻译,而直接执行就可以了。最典型的例子就是C语言。
解释型语言就是没有这个编译的过程,而是在程序运行的时候,通过编译器对程序做出解释,然后直接运行,最典型的例子就是ruby。
由此可知,编译型语言在程序执行之前就已经对程序做出了翻译,所以在运行时就少掉了“翻译”的过程,所以效率比较高。但是我们不能一概而论,一些解释型语言也可以通过解释器的优化来在对程序做出翻译时对整个程序做出优化,从而在效率上超过编译型语言。
此外,随着Java基于虚拟机语言的兴起,我们又不能把语言纯粹的分为解释型和编译型两种.
用JAVA举个例子,Java首先是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成机器文件,所以Java是一个先编译后解释的语言。
4.11.2 Python到底是什么?
其实Python和Java/C#一样,也是一种基于虚拟机的语言,我们先来从表面上简单的解释一下python程序的运行过程:
当我们在命令行中输入“Python hello.py”的时候,其实是激活了Python的解释器,告诉解释器,你要开始工作了。
可以在解释之前,其实执行的第一项工作和Java一样,是编译。
Java hello.java
java hello.class
只是我们在使用Eclipse之类的IDE时,将这两部给融合成一步了而已。其实,Python也一样当我们执行Python hello.py时,他也一样执行了这么一个过程,所以我们应该这样来描述Python: Python是一门先编译后解释的语言。
4.11.3 简述Python的执行过程
在说这个问题之前,我们来说两个概念,PyCodeObject和pyc文件。
我们在硬件上看到Pyc自然不必多说,而实际PyCodeObject则是Python编译器真正真正编译成的结果。
当Python程序运行时,编译的结果则是保存在位于内存中的PyCodeObject中,当Python程序运行结束时,Python解释器则将PyCodeObject写回到pyc文件中。
当Python程序第二次运行时,首先程序会在硬盘中寻找Pyc文件,如果找到,则直接载入,否则就重新上面的过程。
所以我们应该来定位PyCodeObject和pyc文件,我们说pyc文件就是PyCodeObject的一种持久化保存的方式。