python2

概览

https://www.python.org/

Python 是一种面向对象、解释型计算机程序设计语言。语法简洁清晰,强制用空格作为语句缩进。

作为专业的Linux运维,最常用的自动化工具是shell脚本,不过shell脚本它只是众多命令的堆叠,无法称之为一种编程语言,shell脚本最大的优势是用起来最方便,快捷,几乎所有的程序都提供命令行式的交互工具,但是有一些情况诸如操作JSON格式的对象,批量删除大量Kafka topic,这个时候shell也不能说不能实现,但是非常繁琐,维护性贼差,写过教长shell脚本的朋友相信都有体会

除了shell脚本再选一种通用的语言那就是python,支持非常广泛,不用编译,搞快的话,用vi就能编写修改,然后直接在Linux系统里运行,绝大部分Linux发行版默认都安装了python

安装 python

CentOS7 默认安装的python版本是2.7,绝大多数Linux发行版和Mac OS X,系统默认已经自带python,可以用python -V看到

$ python -V
Python 2.7.16
$ python3 -V
Python 3.7.3

用docker安装也是非常方便
https://registry.hub.docker.com/_/python/
daocloud.io/library/python:2.7.13
docker pull python:3.8
docker pull python:2.7.18

Run a single Python script on Docker
docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:2 python your-daemon-or-script.py

一般Linux系统中内置的python是非常关键的基础组件,不能随便卸载,最好也不要随便升级,真要某些服务必须跑在python3下,那最好单独的机器跑这个服务,或者用docker启动,生产系统中一台机器杂糅各种python2和python3的服务,维护起来很麻烦

Windows 安装直接下载一个可执行包一路下一步,Mac也可以这样,比如要在Mac上安装Python3,相关下载地址如下:
https://www.python.org/downloads/release/python-383/
https://www.python.org/downloads/release/python-2718/

代码规范

1) 缩进
Python 以空白符作为语句缩进,意味着语句没有结尾符,刚入门的朋友往往因为上下逻辑代码不对 齐导致运行报错,在 Python 中最好以 4 个空格作为缩进符,严格对齐。
2) 代码注释 据说优质的代码,注释说明要比代码量多,详细的代码说明不管是对自己还是对他人,在后期维护 中都是非常有利的。就像一个流行的开源软件,如果没有丰富的使用文档,你认为会有多少人耐心 的去花大把的时间研究它呢!
3) 空格使用
在操作符两边,以及逗号后面,加 1 个空格。但是在括号左右不加空格。 在函数、类、以及某些功能代码块,空出一行,来分隔它们。
4) 命名
模块:自己写的模块,文件名全部小写,长名字单词以下划线分隔。 类:大/小驼峰命名。我一般采用大驼峰命名,也就是每个单词首字母大写。类中私有属性、私有方 法,以双下划线作为前缀。
函数:首单词小写,其余首字母大写。
变量:都小写,单词以下划线分隔。
所有的命名规则必须能简要说明此代码意义。

交互式解释器

直接执行 Python 命令就启动默认的 CPython 解释器

ndpss-MacBook-Pro:~ ndps$ python
Python 2.7.16 (default, Dec 13 2019, 18:00:32) 
[GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.32.4) (-macos10.15-objc-s on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print "hello-world"
hello-world

退出交互模式
>>> quit()

基础语法

######################################## 运行第一个程序 ########################################
cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-
print "Hello World!"
print "你好 世界!"
EOF
ndpss-MacBook-Pro:tmp ndps$ python xtest.py 
Hello World!

第1行,说明用什么可执行程序运行它,env 会自动搜索变量找到 python 解释器

######################################## 注释 ########################################
# 单行注释
''' 
多行注释 多行注释 
'''

###################################### 加减乘除基本运算 ########################################
>>> print 5 + 3
>>> print 5 - 3

>>> print 5 * 3
>>> print '#'*3
###

除法取整
>>> print 5 / 3
1 

>>> print 5 % 3
2

>>> print 5 ** 3
125

###################################### 赋值操作符 ########################################
>>> v1 = 5 + 3
>>> v1
8

>>> v1 = 5
>>> v1 += 3
>>> v1
8

###################################### 多重赋值 ########################################
>>> x, y = 2, 3
>>> print x,y
2 3

>>> x = y =20
>>> x, y
(20, 20)

###################################### 转义字符 ########################################
\ 字符串太长,换一行接着输入
\'  \" 单引号和双引号
\r 光标
\t TAB键
\v 纵向制表符
\n 换行符

如果不想让转义字符生效,可以用 r 指定显示原始字符串:
>>> print r"Hello \nWorld!"
Hello \nWorld!
>>> print "Hello \nWorld!"
Hello 
World!

###################################### 获取用户输入 ########################################
raw_input()
>>> name = raw_input("My name is: ")
My name is: xiaoming  (执行到这里会夯住,等待用户输入xiaoming,敲回车,继续执行)
>>> print name
xiaoming

input()
>>> name = input("My name is: ")

原因是因为 raw_input()把任何输入的都转成字符串存储。 而 input()接受输入的是一个表达式,否则就报错。
>>> print "xxoo: %d" % xxoo
>>> print "xxoo: %s" % xxoo

>>> x = "abc"
>>> o = 123
>>> print "str: %s, int: %d" % (x, o)

$s 字符串
%d 整数
%f 浮点数

############################### 字符串输出颜色 ###############################

cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-

RED="\033[1;31;40m"
END="\033[0m"
print RED + "HELLO" + END

EOF
python xtest.py

判断变量类型 type()

cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-
a = 123
b = 1.23
print type(a)
print type(b)
EOF

python xtest.py

<type 'int'>
<type 'float'>

字符串

##################### 字符串连接 #####################
>>> hw = "Hello" + "World!"
>>> print hw
HelloWorld!

字符串与其它类型变量的连接
>>> a = "abc"
>>> b = 1
>>> c = "%s %d" % (a, b)
>>> print c
abc 1

OR  c = a + str(b)

##################### 常见的字符串处理方法 #####################
cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-

xxoo = "Hello world!"
print "字符串长度: %s" % len(xxoo)
print "首字母大写: %s" % xxoo.capitalize()
print "字符 l 出现次数: %s" % xxoo.count('l')
print "感叹号是否结尾: %s" % xxoo.endswith('!')
print "w 字符是否是开头: %s" % xxoo.startswith('w')
print "w 字符索引位置: %s" % xxoo.find('w') # xxoo.index('W') 
print "格式化字符串: Hello{0} world!".format(',')
print "是否都是小写: %s" % xxoo.islower()
print "是否都是大写: %s" % xxoo.isupper()
print "所有字母转为小写: %s" % xxoo.lower()
print "所有字母转为大写: %s" % xxoo.upper()
print "感叹号替换为句号: %s" % xxoo.replace('!','.') 
print "以空格分隔切分成列表: %s" % xxoo.split(' ') 
print "转换为一个列表: %s" % xxoo.splitlines()
print "去除两边空格: %s" % xxoo.strip() 
print "大小写互换: %s" % xxoo.swapcase() 
print "只要 Hello 字符串: %s" % xxoo[0:5] 
print "去掉倒数第一个字符: %s" % xxoo[0:-1]

EOF
python xtest.py

Python 编码处理

Python 处理编码流程大致是这样的,ascii --> decode() --> unicode --> encode() --> 终端能识别的编码,unicode 算是一个中间码,有着承上启下的作用

decode()函数作用是将其他编码(比如 ACSII、Byte String)的字符串解码成 Unicode
encode()函数作用是将 Unicode 编码成终端软件能是识别的编码,就能正常显示了,比如 UTF-8、 GBK

Python 数据类型

列表 list

列表很像其它编程语言中的数组

lst = ['a','b','c',1,2,3]
# 打印列表
print lst

# 追加一个元素
lst.append(4)

# 统计列表中 a 字符出现的次数
lst.count('a')

# 将一个列表作为元素添加到 lst 列表中
a = [5,6]
lst.extend(a)

# 查找元素 3 的索引位置
lst.index(1)

# 在第 3 个索引位置插入一个元素
lst.insert(3, 0)

# 删除最后一个元素和第 3 个下标元素
lst.pop()
lst.pop(3)

# 删除元素是 5,如果没有会返回错误
lst.remove("5")

# 倒序排列元素
lst.reverse()

# 正向排序元素
lst.sort()

# 列表连接
>>> a = [1,2,3]
>>> b = ['a','b','c']
>>> a + b

reversed()函数倒序排列
sorted()函数正向排列
和列表内置方法结果一样,区别是内置函数不改动原有序列

########################## 切片(访问列表指定元素) #####################################
# 返回第一个元素
>>> lst[0]

# 返回倒数第一个元素
>>> lst[-1]

# 去掉倒数第一个元素
>>> lst[0:-1]
[1, 2, 3, 4, 'a', 'b']

# 返回第一个至第四个元素 
>>> lst[0:4]

############################# 遍历列表 ##############################################
cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-

#方法1
lst = ['a','b','c',1,2,3]
for i in range(len(lst)):
    print i,lst[i]
print
#方法2
for index, value in enumerate(lst):
    print index,value
EOF


########################## 删除列表中的元素 #####################################
>>> lst = [1, 2, 3, 4, 'a', 'b', 'c'] 
>>> del lst[0:4]
>>> lst
['a', 'b', 'c']

########################## 清空列表 #####################################
>>> lst = [1, 2, 3, 4, 'a', 'b', 'c'] >>> lst = []
>>> lst
[]

>>> del lst
>>> lst
Traceback (most recent call last):
File "<stdin>", line 1, in <module> NameError: name 'lst' is not defined

元组 Tuple

元组与列表类型,不同之处在于元组的元素不可修改。

定义元组
t = ('a','b','c',1,2,3)
用小括号括起来,元素以逗号分隔,字符串用单引号引起来,整数不用。

集合 set

集合是一个无序不重复元素的序列,主要功能用于删除重复元素和关系测试。集合对象还支持联合 (union),交集(intersection),差集(difference)和对称差集(sysmmetric difference) 数学运算。

定义集合
s = set()

# 添加元素
>>> s.add('a')
>>> s.add('b')
添加的元素是无序的,并且不重复的

# update 方法事把传入的元素拆分为个体传入到集合中。与直接 set('1234')效果一样
>>> s.update('1234')

# 删除元素
>>> s.remove('4')

# 删除元素,没有也不会报错,而 remove 会报错 
>>> s.discard('4')

# 删除第一个元素
>>> s.pop()

# 清空元素
>>> s.clear()

# 列表转集合,同时去重
>>> lst = ['a','b','c',1,2,3,1,2,3] 
>>> s = set(lst)

字典 Dict

序列是以连续的整数位索引,与字典不同的是,字典以关键字为索引,关键字可以是任意不可变对 象(不可修改),通常是字符串或数值。 字典是一个无序键:值(Key:Value)集合,在一字典中键必须是互不相同的,比如我们的程序需要存放手机号码,通常key设置成人名,而value设置成手机号

定义字典
d = {'a':1, 'b':2, 'c':3}
用大括号括起来,一个键对应一个值,冒号分隔,多个键值逗号分隔。

# 访问单个元素
>>> d['a']

# 返回所有键值
>>> d.items()

# 返回所有键
>>> d.keys()

# 查看所有值
>>> d.values()

# 添加键值
>>> d['e'] = 4

# 获取单个键的值,如果这个键不存在就会抛出 KeyError 错误
>>> d['a']

# 获取单个键的值,如果有这个键就返回对应的值,否则返回自定义的值no 
>>> d.get('a','no')

# 删除第一个键值
>>> d.popitem()

# 删除指定键
>>> d.pop('b')

# 添加其他字典键值到本字典
>>> d.update(d2)

# 拷贝为一个新字典
>>> dd = d.copy()

# 判断键是否在字典
>>> d.has_key('a')

# 如果字典中有 key 则返回 value,否则添加 key,默认值 None
cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-

d = {
    'a': 1, 
    'c': 3, 
    'e': 4
}

#输出1
print d.setdefault('a', 5)

#输出98
print d.setdefault('b', 98)

#输出 None
print d.setdefault('f')
EOF

ndpss-MacBook-Pro:xtest ndps$ python xtest.py 
1
98
None


####################################### 字典遍历(迭代器) #############################################
d.iteritems()  # 获取所有键值,很常用
d.iterkeys()   # 获取所有键
d.itervalues() # 获取所有值

cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-

d = {
    'a': 1,
    'b': "危楼高百尺-手可摘星辰",
    'c': 3, 
    'e': 4
}

for i in d.iteritems():
    print "key:%s value:%s" %(i[0], i[1])
print

#常用这种
for k, v in d.iteritems():
    print "%s: %s" %(k, v)
print

for i in d.iterkeys():
    print i
print

for i in d.itervalues():
    print i
print
EOF

####################################### 字典嵌套 #############################################
字典可以嵌套其它数据类型(数组,字典等),形成更复杂的结构,比如统计一个班级的同学电话号码:姓名-->电话,两层结构即可,如果是全校同学的电话号码可能就要 班级-->姓名-->电话 三层结构了
cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-

d = {
    'a': 1,
    'b': ["危楼高百尺-手可摘星辰", "不敢高声语-恐惊天上人"],
    'c': 3, 
    'e': 4
}
print d['b'][0]
print d['b'][1]

EOF

数据类型转换

# 转整数
int(i)

# 转浮点数
float(f)

# 转字符串
str(i)

# 字符串转列表
>>> s = 'abc'
>>> lst = list(s)
>>> s.split()

# 列表转字符串
s = ''.join(lst)

######################### 字符串与字典互转 ###############################
cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-
import json

# 方法1
s = '{"a": 1, "b": 2, "c": 3}'
d = eval(s)
# 此时d已经被转换成字典
print type(d)
print d

# 方法2
s = '{"a": 1, "b": 2, "c": 3}'
d = json.loads(s)
# 此时d已经被转换成字典
print type(d)
print d
EOF

######################### 内建函数 join() and eval() ###############################
join()函数是字符串操作函数,用于字符串连接。
>>> s = "ttt"
>>> ".".join(s)
't.t.t'
>>> s = ",".join(t)
'a,b,c'

eval()函数将字符串当成 Python 表达式来处理。
>>> eval('a + 1') 2

运算符

############################## 比较操作符 ##############################
>>> 1 == 1 True
>>> 1 != 1 False
>>> 2 >  1 True
>>> 2 <  1 False
>>> 1 >= 1 True
>>> 1 <= 1 True

############################## 逻辑运算符 ##############################
>>> a and b
>>> a or b

全为 and 时,返回最后一个值。
全为 or 时,返回第一个值。
需要知道的是:在 Python 中空数组、None、False、0、""都为 false,其他都是 true。

if not a:
    print "yes" 
else:
    print "no"

if a:
    print "yes" 
else:
    print "no"

############################## 成员运算符 ##############################
in     在对象里
not in 不在对象里

>>> 'a' in 'abc'
True
>>> 'd' in 'abc'
False
>>> lst = ['a','b','c']
>>> 'a' in lst
True

流程控制

条件判断

######################### 基础 ##################################################
a = 20
if a < 18:
    print "no"
else:
    print "yes"

######################### 三目表达式 ##############################################
a = 20
result = ("yes" if a == 20 else "no")
print result

######################### 多分支 ##############################################
a = 20
if a < 18:
    print "no"
elif a == 20:
    print "yes"
else:
    print "other"

######################### pass语句 ##############################################
pass 语句作用是不执行当前代码块,与 shell 中的冒号做作用一样

a = 20
if a < 18:
    print "no"
elif a == 20:
    pass
else:
    print "other"

循环语句

######################### 基础 ##################################################
for i in "abc":
    print i

for i in range(1,5):
    print i

######################### 嵌套循环 ##################################################
for i in range(1,6):
    for x in range(3,8):
        if i == x:
            print i

######################### while 循环 ##################################################
count = 0
while count < 5:
    print count
    count += 1

######################### 死循环 ##################################################
import time
i = 1
while True:
    print i
    i += 1
    time.sleep(0.5)

######################### continue 语句 ##################################################
for i in range(1,6):
    if i == 3:
        continue
    else:
        print i

######################### break 语句 ##################################################
for i in range(1,6):
    if i == 3:
        break
    else:
        print i

######################### else 语句 ##################################################
else 语句会在循环正常执行完才执行。在 for 循环用法也一样
count = 0
while count < 5:
    print count
    count += 1
else:
    print "end"

函数

函数作用:把一些复杂的代码封装起来,函数一般都是一个功能,用的时候才调用,提高重复利用 率和简化程序结构。

######################### 语法 ##################################################
def functionName(parms1, parms2, ...): 
    code block
    return expression
######################### 函数定义与调用 ##################################################

cat << 'EOF' > xtest.py
#!/usr/bin/env python 
# -*- coding: utf-8 -*-

#定义
def func():
    print "hello-world"
    return "hello-world"

#调用
func()
EOF

######################### 接收参数 ##################################################
def func(a, b):
   print a + b
func(1, 2)

######################### 函数参数默认值 ##################################################
def func(a, b=2):
    print a + b
func(1)
func(1, 3)

######################### 接受任意数量参数 ##################################################
def func(*a):
    print a
func(1,2,3)

单个星号存储为一个元组,两个星号存储为一个字典
def func(*args, **kwargs):
    print args
    print kwargs

######################### 作用域 ##################################################
作用域范围一般是:全局(global)->局部(local)->内置(build-in)
如果函数内部的变量也能在全局引用,需要使用 global 声明: global b

######################### 高阶函数 ##################################################
高阶函数是至少满足这两个任意中的一个条件: 
1) 能接受一个或多个函数作为输入。 
2) 输出一个函数。
abs、map、reduce 都是高阶函数

面向对象

python--面向对象(最全讲解)
https://www.cnblogs.com/Eva-J/articles/7293890.html

异常处理

######################### 捕捉异常语法 ##################################################
try:
    expression
except [Except Type]:
    expression
    
######################### 常见的异常类型 ##################################################
SyntaxError  语法错误
IndentationError  缩进错误
TypeError  对象类型与要求不符合
ImportError 模块或包导入错误
KeyError   字典里面不存在键
NameError  变量不存在
IndexError 下标超出序列范围
IOError   IO错误,一般是无法打开文件
AttributeError 对象里没有属性
KeyboardInterrupt 键盘接收到CTRL+C
Exception   通用的异常类型,一般会捕获所有异常

其它的一些异常类型,可以通过dir查看
import exceptions
dir(exceptions)

异常处理的用途:比如你要打印字典的某个key,这个key可能有,可能没有,没有就会抛出KeyError的错误,你可以捕获住,做其它处理

######################### 异常处理 ##################################################

try:
    print a
except NameError:
    a = ""

在开发中往往不知道什么是什么异常类型,这时就可以使用 Exception 类型来捕捉所有的异常

try:
    print a
except Exception:
    a = ""

有时也想把异常信息也打印出来,怎么做呢? 可以把错误输出保存到一个变量中,根据上面例子来:

try:
    print a
except Exception, e:
    print "Error: " + str(e)

或者使用as

try:
    print(a)
except Exception as e:
    print("Error: " + str(e))

######################### else and finally ##################################################
表示如果 try 中的代码没有引发异常,则会执行 else
try:
    print a
except Exception as e:
    print "Error: " + str(e)
else:
    print "else ..."

表示无论是否异常,都会执行 finally
try:
    print a
except Exception as e:
    print "Error: " + str(e)
finally:
    print "finally ..."
一般用于清理工作,比如打开一个文件,不管是否文件是否操作成功,都应该关闭文件。

######################### try...except...else...finally ##################################################
try:
    print a
except Exception as e:
    print "Error: " + str(e)
else:
    print "else ..."
finally:
    print "finally ..."

需要注意的是:它们语句的顺序必须是 try...except...else...finally,否则语法错误!里面 else 和 finally 是可选的。

第3方模块

比如用python操作MySQL,操作Redis这些都需要提前安装第3方模块来支持

################################### 安装
在 Python 中安装外部的模块有几种方式:
1)下载压缩包,通过 setuptools 工具安装
2)easy_install 工具安装,也依赖 setuptools
3)pip 工具安装。推荐使用这个方式
4)直接将压缩包解压到 Python 模块目录。但常常会出现 import 失败,不推荐

方式 1:
# wget https://pypi.python.org/packages/32/3c/e853a68b703f347f5ed86585c2dd2828a83252e1216c1201 fa6f81270578/setuptools-26.1.1.tar.gz
# tar zxvf setuptools-26.1.1.tar.gz
# cd setuptools-26.1.1
# python setup.py install

方式 2:
# easy_install setuptools

方式 3:
# pip install setuptools
# pip uninstall setuptools
# pip search setuptools

######################## AttributeError: 'module' object has no attribute 'Counter' #####################
在python中文件名就是模块名,所以文件名不要与引用的模块名相同,否则会报错

python 常用标准库

################################################ sys ################################################
1)sys.argv
命令行参数
argv[0] #代表本身名字
argv[1] #第一个参数
argv[2] #第二个参数

import sys
print sys.argv[0]
print sys.argv[1]
print sys.argv[2]
print sys.argv[3]
print sys.argv
print len(sys.argv)

值得注意的是,argv 既然是一个列表,那么可以通过len()函数获取这个列表的长度从而知道输入的参数数量。可以看到列表把自身文件名也写了进去

2)sys.path 模块搜索路径
>>> import sys
>>> sys.path

3)sys.platform 系统平台标识符
Linux               linux 
Windows             win32
Windows/Cygwin      cygwin
Mac OS X            darwin

4) sys.subversion 查看当前python用的解释器
>>> sys.subversion
('CPython', '', '')

6)sys.exit() 退出解释器
退出程序,调试代码常用

7)sys.stdin、sys.stdout 和 sys.stderr
echo "sss" | python b.py

################################################ os ################################################
os 模块主要对目录或文件操作
os.name 返回操作系统类型
os.environ 以字典形式返回系统变量

################################################ math ################################################
数字处理
math.pi 返回圆周率

################################################ json ################################################
# 将字典转换为 JSON 字符串
>>> dict = {'user':[{'user1': 123}, {'user2': 456}]}
>>> type(dict)
<type 'dict'>
>>> json_str = json.dumps(dict) 
>>> type(json_str)
<type 'str'>
# 把 JSON 字符串转换为字典
>>> d = json.loads(json_str) >>> type(d)
<type 'dict'>

文件操作

待补充

https://www.cnblogs.com/zyber/p/9578240.html

Python 数据库编程

Python 正则表达式

Python 网络编程

python2 命令行 格式化JSON格式输出

[root@datapipline as4k]# curl -s -X POST "http://192.168.1.108:5000/v2/users/login" -H "accept: application/json" -H "Content-Type: application/json" -d '{ "login": "monitor", "password": "123456"}' | python -c "import json,sys; obj=json.load(sys.stdin); print obj['data']['token'];"
77mY3CpEIYc/rLgZrcxyq2b5DO0Hng1GLFtYcZgGVacK9upw2xVXWxx+vlM7SfA2av+DMTc4YPbW30G3X9v9Fg==

参考资料

https://github.com/lizhenliang/Shell-Python-Document/blob/master/Python%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B.pdf
Python基础教程.pdf

https://www.python.org/about/gettingstarted/

常见的python IDE
https://wiki.python.org/moin/IntegratedDevelopmentEnvironments

python 书籍推荐
https://wiki.python.org/moin/IntroductoryBooks

python 新手学习资料
https://wiki.python.org/moin/BeginnersGuide/Programmers