估计以后要经常用到NetworkX、Matplotlib,而这两模块是基于Python,决定较为系统学下Python。本文整理了Python语言基本语法、流程控制、自定义函数。

1 基本语法规则

Python是一种面向对象(万物皆对象)、解释性脚本语言,支持命令式程序设计、面向对象程序设计、函数式编程、面向方面的程序设计(Aspect-oriented programming,AOP)、泛型编程多种编程范式。Python语言的核心只包含数字、字符串、列表、字典、文件等常见类型和函数,而强大的Python标准库提供文本处理、文件处理、系统管理、网络通信、数据库接口、图形系统、XML处理等额外的功能。除此之外,Python社区提供了大量的第三方模块(可在https://pypi.python.org/pypi查询),如NetworkX、Matplotlib[1]。

1.1 创建与运行脚本

(1)创建

第一行#!/usr/bin/python指定解释器(或者用#!/usr/bin/env python,更具可移植性[3]),建议还是加上。文件后缀名(通常是.py)也不是必须的,但为了管理方便,建议加上。

Python内部用的是unicode编码。对于Python 2,要让python支持中文,需添加# -*- coding: utf-8 -*-。Python3.x默认使用utf-8编码[6],可以不用加。

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

(2)运行

./test.py         # 执行前需给脚本加上执行权限(chmod u+x test.py)
python test.sh    # 加执行权限不是必须的

1.2 注释与缩进

(1)注释

单行注释:用井号#。Python不支持多行注释,但可以借助三引号将注释代码定义为多行字符串。如下:

"""
...注释内容
""" 

'''
...注释内容
'''

(2)缩进

不同于大多数程序设计语言使用大括号表示语句块,Python使用缩进定义语句块。每条语句结尾不需要加分号,但可用分号在一行连接多条语句。

1.3 变量

变量名称的首个字符必须是大小写字母或者下划线,不能是数字。变量直接赋值,不需要事先声明或定义数据类型。

(1)数值类型 Python有4种类型的数,即整型、长整型、浮点型和复数。

  • 整型:包括布尔值True,False。八进制以0开头,十六进制以0x(X)开头
  • 长整型:无限大小的数(受限于虚拟内存),结尾添加l或L
  • 浮点型:十进制或科学计数法(e或E表示10,+/-)表示,如5.0e-2
  • 复数:实数部分+虚数部分j/J,如7+3j

关于数值类型可以进一步参考《Python基础:数值(布尔型、整型、长整型、浮点型、复数)》。Python标准库与数值类型相关的模块(Numeric and Mathematical Modules)如下[4]:

  • numbers Numeric abstract base classes
  • math Mathematical functions
  • cmath Mathematical functions for complex numbers
  • decimal Decimal fixed point and floating point arithmetic
  • fractions Rational numbers
  • random Generate pseudo-random numbers
  • itertools Functions creating iterators for efficient looping
  • functools Higher-order functions and operations on callable objects
  • operator Standard operators as functions

还有高级数据科学计算的第三方包,NumPy和ScipPy。参数书籍《用Python做科学计算》。

(2)字符串

  • 单引号('):指示字符串
  • 双引号("):指示字符串,单引号不需要转义
  • 三引号('''"""):指示多行的字符串,单引号和双引号不需要转义
  • 自然字符串:指示不需要特别处理的字符串(如转义符),在字符串前加r或R来,如:r"Hello\n"

内建类型(Build-in Type)str,包含一系列操作,使用方法如下:

class str(object='')
class str(object=b'', encoding='utf-8', errors='strict') 

str(object) returns object.__str__(),

关于字符串相关模块如下:

string    # Common string operations
re        # Regular expression operations

(3)元组Tuple

  • 任意对象的有序集合,如t = (1, 2, "abc")
  • 一旦生成不可改变t[0] = 2是错误的)
  • 通过偏移读取(t[-1]为abc),支持任意嵌套

(4)列表List

  • 任意对象的有序集合,如l = [1, 2, “abc”]
  • 列表元素可变,如l[1]=[4, 5, 6], l[1:]=[7, 8, 9]
  • 通过偏移读取(l[-1]为abc),支持任意嵌套

list的一些操作点这里,list可以当作堆、队列使用。list一些操作如下:

list.append(x)     # Equivalent to a[len(a):] = [x].
list.extend(L)     # Equivalent to a[len(a):] = L.
list.insert(i, x)  # a.insert(0, x) inserts at the front of the list
list.remove(x)     # Remove the first item from the list whose value is x. 
list.pop([i])      # a.pop() removes and returns the last item in the list. 
list.clear()       # Equivalent to del a.
list.index(x)      # Return the index of the first item whose value is x. 
list.count(x)      # Return the number of times x appears in the list.
list.sort()        # Sort the items of the list in place.
list.reverse()     # Reverse the elements of the list in place.
list.copy()        # Return a shallow copy of the list. Equivalent to a.

(5)字典dict

  • 键-值对的集合,键和值可以是任意对象,如d = {1:”a”, 2:”b”}
  • 键-值对无序
  • 通过键来存储,支持任意嵌套

字典的一些操作点这里

1.4 打印信息

(1)调用格式

值得注意的是,Python3.x(#! /usr/bin/python3)去除了print语句,以print()函数代替。print函数调用格式如下:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

可见,print函数支持可变参数*objects,参数间默认以空格分隔,输出默认以一个换行符结束,默认输出到标准输出,默认不清空缓存。如:print("aaa", "bbb", sep='\t', end='!!!')

(2)格式化输出

格式化输出字符串,一种方法是用百分号格式化字符串,使用方法如下:

# "字符 %格式1 %格式2 字符" %(变量1,变量2)   理解成:前两个%是占位符,后面是变量替换
print("His age is %d" %(25), "bbb")

还有一种方法,使用内置函数format,使用方法如下[9]:

format(value[, format_spec]) 

print("This kind of {tea}".format(tea="Tie Guanyin"))

1.5 下划线

Python用下划线指示特殊变量,概括如下[5][7]:

# 变量
_xxx      # 标明是一个私有变量, 只用于标明, 外部类还是可以访问到这个变量
__xxx     # 类中私有变量
__xxx__   # 内置变量,系统定义的名字,如__init__()代表类的构造函数
XXX_XXX   # 不会发生改变的全局变量 

# 函数
_xxx     # 标明是一个私有函数, 只用于标明
__xxx__  # 标明是特殊函数,如操作符重载

注:使用from mymodule import *加载模块时,不会加载以单下划线开头的模块属性。

参考资料[8]所说的,似乎跟上面有些矛盾,先放着吧,如下:

  • “单下划线” 开始的成员变量叫做保护变量,只有类对象和子类对象自己能访问到这些变量
  • “双下划线” 开始的是私有成员,只有类对象自己能访问,连子类对象也不能访问到这个变量

Python官方文档,搜索双下划线,得到如下结果:

  • __future__ (Python module, in 29.10. __future__ — Future statement definitions)
  • _main_ (Python module, in 29.4. __main__ — Top-level script environment)
  • _cached_ (Python attribute, in 5. The import system)
  • _debug_ (Python data, in 3. Built-in Constants)
  • _file_ (Python attribute, in 5. The import system)
  • _import_ (Python function, in 2. Built-in Functions)
  • _loader_ (Python attribute, in 5. The import system)
  • _name_ (Python attribute, in 5. The import system),指示模块如何被加载
  • _package_ (Python attribute, in 5. The import system)
  • _path_ (Python attribute, in 5. The import system)
  • _spec_ (Python attribute, in 5. The import system)

1.6 调用shell命令[11]

import os
os.system(cmd)  # 只返回命令运行结果,不过取不了返回值
os.popen(cmd)   # 要得到命令的输出内容,只需再调用下read()或readlines()等,如:os.popen(cmd).read() 

import commands                 # 其实是对popen的封装
commands.getstatusoutput(cmd)   # 返回(status, output).
commands.getoutput(cmd)         # 只返回输出结果
commands.getstatus(file)        # 返回ls -ld file的执行结果字符串

1.7 命令行参数传递

有时候需要向python脚本文件传递参数(如文件名),Python利用模块sys.argvsys.argv实为一个list,存储所有命令行参数,sys.argv[0]是脚本名称本身,len(sys.argv)可以得到总参数个数。举例如下:

# 运行脚本
python test.py arg1 arg2 

# python脚本
#!/usr/bin/env python
import sys
if len(sys.argv) < 3 :
    sys.exit(0)
arg1 = int(sys.argv[1])
arg2 = float(sys.argv[1])

2. 流程控制

2.1 条件表达式

更多内容查看python官方文档内建类型Built-in Types.

(1)真假

  • 假:None, False, 数值为0(包括0, 0.0, 0j), 空系列('', (), []), 空映射({}
  • 真:除了上述假值外,其他值视为真值

(2)布尔操作Boolean Operation

x or y         # if x is false, then y, else x
x and y        # if x is false, then x, else y
not x          # if x is false, then True, else False

注:not优先级比non-Boolean操作符还低,如not a == b视为not (a == b).

(3)比较符

<         # strictly less than
<=        # less than or equal
>         # strictly greater than
>=        # greater than or equal
==        # equal
!=        # not equal
is        # object identity
is not    # negated object identity

注:上述比较符的优先符一样,另x < y <= z相当于 x < y and y <= z

(4)整数位操作

x | y         # bitwise or of x and y     
x ^ y         # bitwise exclusive or of x and y     
x & y         # bitwise and of x and y     
x << n        # x shifted left by n bits
x >> n        # x shifted right by n bits
~x            # the bits of x inverted

(5)数值操作

-x                  # x negated
+x                 # x unchanged
x + y            #sum of x and y
x - y            #difference of x and y
x * y            # product of x and y
x / y            # quotient of x and y
x // y           # floored quotient of x and y
x % y            # remainder of x / y
divmod(x, y)     # the pair (x // y, x % y)
pow(x, y)        # x to the power y
x ** y           # x to the power y 

abs(x)           # absolute value or magnitude of x
int(x)           # x converted to integer
float(x)            # x converted to floating point
complex(re, im)  # a complex number with real part re, imaginary part im. imdefaults to zero.
c.conjugate()    # conjugate of the complex number c

(6)序列操作list,tuple,range

x in s        # True if an item of s is equal to x, else False
x not in s    # False if an item of s is equal to x, else True 
s + t            # the concatenation of s and t
s * n or n * s    # n shallow copies of s concatenated 

s[i]        # ith item of s, origin 0
s[i:j]        # slice of s from i to j
s[i:j:k]    # slice of s from i to j with step k 

len(s)    # length of s
min(s)    # smallest item of s
max(s)    # largest item of s 

s.index(x[, i[, j]])    # index of the first occurrence of x in s (at or after index i and before index j) 

s.count(x)    # total number of occurrences of x in s

(7)range

class range(stop)
class range(start, stop[, step]) 

>>> list(range(10))[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

for integer in range(10):

2.2 if

if 表达式1 :
    语句体1
elif 表达式2 :
    语句体2
...
elif 表达式m :
    语句体m
else :
    语句体n

2.3 for

for 控制变量 in 可遍历的表达式:
    循环体

值得注意的是,for循环可以加else子句,形式如下。for语句在遍历所有元素的过程中,若从未执行break语句,那么else子句内嵌的语句体将得以执行;一旦执行break语句,程序流程将连带else子句一并跳过。

for 控制变量 in 可遍历的表达式:
    循环体
else:
    语句体

2.4 while

while 表达式 :
    循环体

同for语句类似,while循环可以加else子句,形式如下。while语句在遍历所有元素的过程中,若从未执行break语句,那么else子句内嵌的语句体将得以执行;一旦执行break语句,程序流程将连带else子句一并跳过。

while 表达式 :
    循环体
else:
    语句体

2.5 break/continue/pass

同C语言一样,break语句跳出当前循环,continue语句跳出当前循环进入下一个循环。Python流程控制if,for,while至少需要包含一条语句,而pass语句表示什么都不做(相当于shell脚本语言中的分号,表示什么都不做)。

2.6 读取外部文件

Python提高多种方法将外部文件读入,罗列几种如下:

# 读到数组(实为列表list)
with open(msg_report_file) as f_report :
    lines_report = f_report.readlines()[1:] # skip the first line    
    nrofLines_report = len(lines_report)    
    f_report.close() 

# 逐行读取,相当于f = open("foo.txt");line = f.readline()
for line in open(sys.argv[1]) :  
    strlist = line.split()  
    n1 = int(strlist[0])  
    n2 = int(strlist[1])

3. 函数

def 函数名(参数列表):
    函数体

3.1 内建函数

内建函数参见官方文档Python documentation: Built-in Functions

4. 学习资料

参考资料:

[1] 维基百科词条:Python

[2] Swaroop, C. H. 沈洁元译.简明Python教程[M]

[3] 博文《千万不要把Python脚本的第一行写成“#! /usr/bin/python”

[4] 博文《Python基础:数值(布尔型、整型、长整型、浮点型、复数)

[5] 博文《Python中内建变量的使用

[6] 博文《Python3.x和Python2.x的区别

[7] 博文《关于python中带下划线的变量和函数的意义

[8] 博文《Python中下划线—完全解读

[9] 博文《Python – 格式化(format())输出字符串 详解 及 代码

[10] 博文《循序渐进学Python:三种选择语句

[11] 博文《python 学习笔记 8 — Python下调用Linux的Shell命令

本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-03-17 16:02

results matching ""

    No results matching ""