运维Python大全

  • 运维Python大全
    • INSTALL PYTHONE3
    • Python syntax
      • 标题 合法的变量名,有三个要求
      • 1. 推荐采用的全名方法
      • 2. 标准算术运算符 + - * / // % **
      • 3. 比较运算符
      • 4. 逻辑运算符
    • 一 、python 数据类型
      • 1. 数字
      • 2. 字符串
      • 3.字符串切片
      • 4. 列表
      • 5. 元组
      • 6. 字典
    • 二、判断语句
      • 1. if 判断
      • 2. while循环
      • 3. 三元运算符,也叫条件表达式
      • 4. for循环
    • 三、实战案例应用
    • 四、文件对象
      • 1. 文件操作的基本步骤 -> 打开、读写、关闭
      • 2. 实操:在Linux服务器操作
      • 3. seek 和tell方法不常用,选修
      • 4. with
      • 练习:模拟cp操作
    • 五、函数
      • 1. 定义参数
      • 2. 模块:
      • 练习:生成随机密码
      • 3. shell 相关模块
      • 4. 变量赋值
      • 5. 多元赋值
      • 6. 合法标识符
      • 7. 关键字
      • 练习:查看有哪些关键字
      • 8. 内键
      • 9. 程序风格
      • 10. 编写程序的流程、步骤
      • 11. 序列类型操作符
      • 12. 内建函数(工厂函数)
      • 13. 字符串操作符
      • 14. 检查标识符
      • 15. 字符串格式化
      • 16. format函数
      • 练习:创建用户(Linux系统运行)
      • 17. 原始字符串操作符
      • 18. 字符串内建函数 (字符串操作)
      • 19. 字符串方法
      • 20. 创建及访问列表(列表list操作)
      • 20. 列表内建函数
      • 21. 单元素元组必须有逗号,否则不表示元组
      • 练习: 用列表构建栈结构
      • 22. 字典和集合/文件系统
      • 练习:通过key更新字典
      • 23. 字典内建方法
      • 24. Windows文本换行和Unix转换
      • 练习:编写类进度条程序
      • 25. 集合
      • 26. 集合类型操作符
      • 27. 集合内建方法
    • 六、简单模块
      • 1. time 模块
      • 2. datetime模块
      • 3. 异常
      • 异常处理 try - except 和try - finally
      • 4. OS模块
      • 5. pickle存储器
      • 练习:记账程序
    • 七、函数应用
      • 1. 函数定义
      • 2. 函数操作符
      • 2. 参数组
      • 练习:简单的加减法数学游戏
      • 4. lambda 匿名函数
      • 5. filter 函数
      • 6. map 函数
    • 八、函数高级应用
      • 1. 变量作用域
      • 2. 函数式编程
      • 3. 偏函数
      • 4. 递归函数
      • 5. 生成器
      • 生成器练习:每次获取文件10行数据
      • 6. 内部函数
      • 7. 闭包
      • 闭包练习:-->创建通用的计数器
      • 8. 装饰器
    • 九、什么是模块
      • 1. 模块导入方法
      • 2. hashlib 模块
      • 3. tarfile模块
      • 练习:备份程序
    • 十、OOP(面向对象编程)
      • 1. 基本概念
      • 2. 创建类
      • 2. 子类
      • 3. 多重继承
      • 3. 静态方法
      • 4. 类方法
    • 十一、 search 函数
      • 1. findall
      • 2. finditer
      • 3. split
      • 4. sub
      • 5. compile
      • 练习:分析Apache访问日志
    • 十二、 re模块(正则)
      • 1. 匹配单个字符
      • 2. 匹配一组字符
      • 3. 其他元字符
      • 4. 贪婪匹配
    • 十三、socket模块
      • 1. 套接字
      • 2. 面向连接与无连接
      • 3. Python字符串str和bytes类型转换
      • 3. TCP
      • 创建TCP服务器
      • 创建TCP客户端
      • 4. UDP
      • 创建UDP服务器
      • 创建UDP客户端
      • UPD服务器循环
      • UDP客户端循环

运维Python大全

INSTALL PYTHONE3

安装依赖包

yum  -y install gcc gcc-c++  zlib-devel openssl-devel readline-devel libffi-devel sqlite-devel tcl-devel tk-devel
wget https://www.python.org/ftp/python/3.8.13/Python-3.8.13.tgz
tar zxf Python-3.8.13.tgz
cd Python-3.8.13
./configure --prefix=/usr/local
make&&make install

安装 Pycharm
Pycharm 设置中文

  1. baidu.com search Pycharm2017.3 汉化包
  2. 下载resource_cn.jar
  3. 把resource_cn.jar 拷贝到/root/bin/pycharm2017/lib中
  4. 如果经过第三步,仍然是英文界面,可以将lib目录中的resource_en.jar先剪切到别处
  5. 启动Pycharm,将报错
  6. 关闭pycharm后,把resource_en.jar再拷贝进去

Pycharm使用
加注释 : 选择行数 crtl +? 去掉注释:crtl+?
; 允许同一行但不推荐


Python syntax

例如;
分开写
a=3
b=4 推荐 这种写法

一行写(不推荐)
a=3;b=4 # 不推荐,可读性差
Python中 “字符串” 必须有引号,单双引号表示相同的含义,
如果不加引号,Python会把它当成一个名称,如果该名称没有定义将会报错

print('hello world')               #语句各项之间默认用空格分隔
print('hello','world')
print('hello','world',sep='***')  #语句各项之间也可以自定义分隔符
print('hello'+'world')                #字符串可以使用+进行拼接
print('hello world',end='AAA')  #print语句默认最后加入一个回车\n,可以用end来自定义结束username = input('请输入用户名:')
print('欢迎登录',username)
print('欢迎登录'+ username)

标题 合法的变量名,有三个要求

  1. 首字符必须是字母或下划线
  2. 其他字符可以是字母、数字或下划线
  3. 区分大小写

1. 推荐采用的全名方法

-变量名全部采用小写字母
-简短、有意义
-多个单词间用下划线分隔
-变量名用名词,函数名用谓词(动词+名词)
-类名采用驼峰形式

n=n+1 或者n+=1 n*=1 #等价于n=n*1
赋值语句自右向左运算,首先取出n的值,再计算n+1的值得到11,最后11赋值给n

2. 标准算术运算符 + - * / // % **

5/2 值为2.5
5//2 值为2 取整除 - 返回商的整数部分(向下取整)
5%2 值为1 求余,也被称作模运算,结果为1
2**3 值为8 2的3次方,乘方、幂运算

3. 比较运算符

< <= > >= == != <>
10<20<30 支持连续比较
10<20>15 相当于10<20 and 20>15 不推荐10<20>15这样的写

4. 逻辑运算符

and not or
and 两边为true
not 假变正
or 一个为正就为正

今天写到   print()    input()https://www.jianshu.com/      搜索“ python百例 "  从下面开始做  1-5
 print('hello world!')
if 3>0:print("ok")print("yes")
x = 4
y = 5
print("hello world!")
print("hello","world!")             # 逗号自动添加默认的分隔符:空格
print("hello"+"world")                # 加号表示字符拼接
print("hello","world",sep="***")  #单词间用 *** 分隔
print("#" * 50)                          #   *号表示重复50遍
print("how are you?",end="")  #   默认print会打印回车,end=“ ” 表示不要回车number = input("请输入数字: ")  # input用于获取键盘输入
print(number)
print(type(number))  # input获得的数据是字符型
print(number + 10)  # 报错,不能把字符和数字做运算
print(int(number) + 10)  # int可将字符串10转换成数字10
print(number + str(10))  # str将10转换为字符串后实现字符串拼接

################################################################################################

一 、python 数据类型

1. 数字

(1)int整数(有符号整数,没有小数点)
(2)bool布尔值 :Ture/false Ture=1 , false=0
(3)float浮点数:有小数点
(4)complex复数:共轭复数
对于整数,没有任何前缀Python默认识别为10进制数
以0o开头表示8进制,0b开头表示2进制 , 以0x开头表示16进制

2. 字符串

在引号中一系列字符,单双引号没有区别
三引号:三个连续的单引号或者双引号。它能够保存输入的格式,允许多行输入

3.字符串切片

下标和切片操作
第一个字符索引是0 ,最后一个字符的索引是-1
索引下标运算符[ ] 切片运算符[:] [::2] 表示步长值

py_str="Python"
len(py_str)        #查询长度
print("len(py_str)")  #打印py_str变量的长度
py_str[0]           #下标从0开始"Python"[0] 意义一样
print(py_str[0])   #可以截取字符串第一个字符
py_str[6]            #索引超出范围,报错
py_str[len(py_str) -1]   #字符串总长度减一,得到最后一个字符的下标
py_str[-1]       #也可以得到最后一个下标py_str[2:4]   #表示下标包含,结束下标不包含
py_str[2:6]   得到 ‘thon’
py_str[2:600]  #下标超出范围,切片不报错 ‘thon’
py_str[2:]     #结束下标不写,表示取到结尾
py_str[0:2]   得到‘py’
py_str[:2]    得到 ‘py’  #开始下标不写,表示从开头开始
py_str[2:5]   得到  "tho"  #从2开始到5结束 5-2=3
py_str[::2]   得到   "pto"    #表示步长值是2
py_str[1::2]   得到  "yhn"   #从1开始步长值是2
py_str[::-1]   得到  "nohtyp"  #表示从右向左取步长值为-1 py_str + " is cool"    #+号表示简单拼接
print(py_str + " is cool" )  得到 Python is cool
"*" * 50         # *号重复50次
print("*" * 50)  得到 **********************************
print(py_str * 3) 得到 PythonPythonPython"t"  in py_str
print("t"  in py_str )   得到 True
"to"  in py_str
print("to"  in py_str  ) 得到 False
print("to"  not in py_str  )   得到 True

4. 列表

可以将列表当成普通的“数组" ,它能保存任意数量,任意类型的Python对象
列表: 它是一个容器,可以存放各种数据

列表

alist = [10 ,20 ,"li" ,"da",[1,2]]
print(len(alist))   得到5
alist[2:4]
print(alist[2:4])  得到 ["li","da"]
alist[-1] =100     #列表项可以重新赋值
print(alist)   得到[10,20,"li","da","100"]
alist.append(200)    #向列表尾部增加一项
print(alist)   得到 [10,20,"li","da","100","200"]

5. 元组

相当于是静态的列表,它的项目不可变

atuple =(10,20,"li","da")
atuple[-1]
print(atuple[-1])  得到  da
atuple[0] =100  #报错,元组不能修改

6. 字典

采用key:val 对存储的数据类型,key不能重复

adict={"name":"大锤","age":18}
adict["name"]          # 通过key取出value
print(adict["name"])  得到 大锤
18 in adict   得到 Flase
"age" in adict  得到True
adict["sex"]="female"   #key不在字典中则增加一项
print(adict)     得到{"name":"大锤","age":18,"sex":"female"}
adict["age"]=20            # age已是字典的key,修改age的值
print(adict)    得到{"name":"大锤","age":20,"sex":"female"}

—————————————————————————————

按数据类型比较 -----------------------重要、必须背下来
按存储模型分类
-标量类型 : 数值、字符串 标量:只有一种类型,不能存储其他类型。数字、字符串
-容器类型:列表、元组、字典 容器:能包含各种数据。列表、元组、字典

按更新模型分类
-可变类型:列表、字典
-不可变类型:数字、字符串、元组

按访问模型分类
-直接访问:数字
-顺序访问: 字符串、列表、元组
-映射访问:字典


例如:

alist = [10 ,20 ,"li" ,"da",[1,2]]
blist = alist
blist.append(30)
print(alist) 得到[10 ,20 ,"li" ,"da",[1,2],30]
print(blist)  得到  [10 ,20 ,"li" ,"da",[1,2],30]   变得一样所以写程序容易出现bugblist=alist.copy()
blist.append(30)
print(alist) 得到[10 ,20 ,"li" ,"da",[1,2]]
print(blist)  得到  [10 ,20 ,"li" ,"da",[1,2],30]

二、判断语句

1. if 判断

words = "tom\njeff\njay\nmikes"
if "tom" in words :print("yes")
if "tom" not in words :print("not in")
else:print("tom in words")if -0.0 : print("0k")             #任何值为0的数字都是False,非0为True  //这里不打印if -0.01 :print("-0.01 is ok")    #这里可以打印Trueif  '  ' :print("space is true")   #任何非空对象都是True ,空位False ,打印
if  '' :print("空字符串是False")  #False不打印
if None:print("None也是False,表示空")   #False不打印

判断合法用户

  1. 创建login2.py
  2. 提示用户输入用户名和密码
  3. 获取相关信息后,将其保存存在变量中
  4. 如果用户的用户名为bob,密码为123456,则输出Login successful,否则输出Login inorrect

###############################################################################################

2. while循环

判断合法用户

  1. 创建login2.py文件
  2. 提示用户输入用户名和密码
  3. 获取相关信息后,将其保存在变量中
  4. 如果用户输的用户名为bob,密码为123456,则输出
    Login successful ,否则输出Login inorrect
import getpass   #导入名为getpass 的模块
username = input("username:")
password = getpass.getpass("password:")if username == "bob" and password == "123456" :print("Login successful")
else:print("Login inorrect")

import random
number = random.randint(1,100)   #生成1-100间的随机数字,包含1和100
print("number ->",number)
answer = int (input("猜数1-100:"))    #将用户输入的字符数字转成真正的int数字if answer > number:print("猜大了")
elif answer< number:print("猜小了")
else:print("猜对了")

import random
number = random.randint(1,100)
while True:answer = int(input("\033[34;1m猜数1-100:\033[0m"))if answer > number :print("\033[34;1m猜大了\033[0m")elif answer <number:print("\033[34;1m猜小了\033[0m")else:print("\033[31;1m猜对了[\033[0m")break

import random
all_choise = ['石头', "箭头", "布"]
win_list = [['石头', '剪刀'], ['布', '石头'], ['剪刀', '布']]prompt = """1.石头
2.剪刀
3.布
请出拳(0/1/2):"""computer = random.choice(all_choise)
index = int(input(prompt))
player = all_choise[index]
print("你的出拳:", player, "计算机出拳:", computer)
if player == computer:print("\033[32;1m平局\033[0m")
elif [player, computer] in win_list:print("\033[35;1m你赢了\033[0m")
else:print("\033[31;1m你输了\033[0m")

import random
tries = 0   #设置计数器,用户最多猜3次
number = random.randint(1,10)while tries<3:answer = int(input("猜数(1-10):"))if answer > number:print("猜大了")elif answer < number:print("猜小了")else:print("猜对了")breaktries +=1
else:print("数字是:",number)

————————————————————————————————————---------------

3. 三元运算符,也叫条件表达式

例如:

      a = 100b = 80
if a<b:smaller = a
else:smaller =b

以上 写法,可简写为

smaller = a if a<b else b

score = int(input("请输入你的成绩:"))if 70>score>=60:print("及格")
elif 80>score>=70:print("良")
elif 90>score>=80:print("好")
elif score>=90:print("优秀")
else:print("你要努力了")

##################################################################################################

4. for循环

for i in  :
range(10)  生成列表[0,1,2,3,4,5,6,7,8,9,]
range(6,10)  生成[6,7,8,9,]

例如:
range(5)
print(list(range(5))) //用list函数 把range(5) 转换成列表
得到 [0, 1, 2, 3, 4]

for i in range(3):                  #[0,1,2]  外侧循环控制打印哪一行for j in range(i+1):            #[0] [0,1] [0,1,2] 内层循环控制行内打印几次print("hello",end=" ")     #多个hello打印到同一行print(j)print()                                 #每一行结尾需要打印回车,否则就成为一行
"%sX%s=%s"  %(1,2,2)    #得到 1X2=2   注释符里面不可以加变量可以加 字符串输出%s占位

打印9*9 乘法表

for i in range(1,10):for j in range(1,i+1):print("%sx%s=%s" %(j,i,i*j),end="\t")   print()

三、实战案例应用

列表解析:快速生成列表

[10]    #得到[10]
[10+5]  #得到[15]
[10+5 for i in range(1,11)]   #得到 [15, 15, 15, 15, 15, 15, 15, 15, 15, 15] [10+i  for i in range(1,11)]   #得到 [11, 12, 13, 14, 15, 16, 17, 18, 19, 20][10+i  for i in range(1,11) if i % 2 == 1]  #得到  [11, 13, 15, 17, 19]["192.168.1."+str(i) for i in range(1,5)]   #得到  ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4']

四、文件对象

1. 文件操作的基本步骤 -> 打开、读写、关闭

open及file file Python2才有,Python3已经不用了,用open
open read readline readlines close

2. 实操:在Linux服务器操作

cp /etc/hosts /tmp/hosts
#打开文件,没有指定打开方式,默认以r 读的方式打开,以r打开,不能写。文件不存在则报错
python3
f = open(“/tmp/hosts”) #默认加r打开了
data = f.read() # read 默认将全部内容读入内存
f.close() #关闭文件
print(data)
data #可以查看到原始数据,也就是\n 没有被转换成换行。

f = open("/tmp/hosts")
f.read(10)              #读取10个字节
f.read(10)              #继续向后读10个字节
f.readline()            #读一行
f.readlines()           #所有的行读出来放到列表中,每一行是列表的一项
f.close()

练习

f = open("/bin/ls","rb")   #打开文本文件,必须明确指定是b(bytes) 二进制文件要加b,要不会报错
f.wirte("jsdf")                   #报错  ,以r打开不能写入只能读
f.read(10)
f.close()
f = open("/tmp/zhuji","w")     #以w打开文件,文件不存在则创建,存在则清空  (慎用)
f = open("/tmp/zhuji","wb")    #清空或者创建可以写入图片
f.write("hello world!\n")            #写入13个字节
f.flush()                                    #立即将数据写入硬盘,否则将会暂存在缓冲区
f.wirtelines(["2nd line.\n","3rd line.\n"])
f.wirte(100)                 #报错,只能将字符写到文件,不能是其他数据
f.close()f =open("/tmp/zhuji","a")   #a是追加方式打开(为了打开可以写入不清空)
f.wirte("new line.\n")

3. seek 和tell方法不常用,选修

f = open("/tmp/zhuji","r+")    #以读写方式打开
f.write("abcde")                      #abcde 将会在开头把原文件覆盖
f.tell()                                    #获取文件指针的位置
f.read(8)                                 #从文件指针开始的位置向后读8个字符
f.seek(3,0)                               #将文件指针称动到开头偏移3个字节
f.read(2)                                   #读文件第4、5 个字符
f.seek(0,2)                                 #移动指针到文件结尾
f.write("my test.\n")
f.flush()
f.read()                                     #因为已经到文件结尾,所有读到的是空串
f.seek(0,0)                                 #移动指针到文件开头
f.readline()

#读第一行的内容

###########################################################################################

4. with

文件操作可以使用with语句,with语句结束时,文件自动关闭

whit open("/tmp/zhuji") as f:                     #相当于 f = open("/tmp/zhuji")...      line  = f.readline()
line                                                #文件第一行
f.readline()

#出错,因为文件已经关闭
逐行处理文本文件,更常用的方法是for循环

>>> with open("/tmp/zhuji")  as f:
...   for line in f:
...       print(line,end=" ")

练习:模拟cp操作

  1. 创建cp.py 文件
  2. 将/bin/ls 拷贝 到/root/目录下
  3. 不要修改原始文件

参考代码:

src_fname = "/bin/ls"
dst_fname = "/tmp/list"src_fobj = open(src_fname,"rb")
dst_fobj = open(dst_fname,"wb")while True:data = src_fobj.read(4096)if not data:                 #读不到数据,意味着已经读完了breakdst_fobj.write(data)     #读到数据,则写入目标文件
src_fobj.close()
dst_fobj.close()

或者

src_fname = "/bin/ls"
dst_fname = "/tmp/list"with open(src_fname,"rb") as src_fobj:with open(dst_fname,"wb") as dst_fobj:while True:data = src_fobj.read(4096)if not data:breakdst_fobj.write(data)

#################################################################################################

五、函数

函数是用def 语句来创建的,语法如下:

def function_name(arguments):
"function_documentation_string"
function_body_suite

例如:

def generate_fib():fib = [0,1]for i in range(8):fib.append(fib[-1]+fib[-2])return fib
generate_fib()                  #调用函数,即将函数内的代码运行一遍
alist = generate_fib()
print(alist)
blist = [i*2 for i in alist]
print(blist)

def generate_fib(n):fib = [0,1]for i in range(n-2):fib.append(fib[-1]+fib[-2])return fiba = generate_fib(10)
print(a)
b = generate_fib(20)
print(b)
x = int(input("length:"))
c = generate_fib(x)
print(c)

——————————————————————————————————————

1. 定义参数

  1. 形式参数(形参)
  2. 实际参数(实参)
  3. 默认参数
    –函数定义时,紧跟在函数名后(圆括号内)的参数被称为形式参数,简称形参。
    由于它不是实际存在变量所以又称虚拟变量
    –实际参数
    –在主调函数中调用一个函数时,函数名后面包括弧中的参数(可以是一个表达式)
    “实际参数”,简称实参
    –默认参数,定义函数时的设置默认参数

import sysprint(sys.argv)           #sys.argv是模块中名为argv的列表,用于存储位置参数

写一个cp命令 在Linux运行

import sys
def copy(src_fname,dst_fname):          with open(src_fname,"rb") as src_fobj:with open(dst_fname,"wb") as dst_fobj:while True:data = src_fobj.read(4096)if not data:breakdst_fobj.write(data)
copy(sys.argv[1],sys.argv[2])

def pstar(n=30)print("*"*n)pstar()    #调用函数默认为打印30
pstar(50)  #打印50

—————————————————————————————————————————

2. 模块:

模块就是一个.py的文件,把文件名的.py移除掉就是模块名
比如:一个文件夹有两个文件star.py 和test.py

star.py中:hi = "hello world!"
def pstar(n=30):print("*"*n)test.py 中:
import star
print(star.hi)
star.pstar(10)在cp.py 中使用import star 就是使用star模块

练习:生成随机密码

创建randpass.py 脚本,要求如下:

  1. 编写一个能生成8位随机密码的程序
  2. 使用random的choice函数随机取出字符
  3. 改进程序,用户可以自己决定生成多少位的密码

参考代码:

import random
import string
all_chs = string.ascii_letters+string.digits def randpass(n=8):result =""for i in range(n):ch = random.choice(all_chs)result+=ch         return resultif __name__ == '__main__':a = randpass()print(a)print(randpass(4))

################################################################################################

3. shell 相关模块

import shutil f1 = open("/etc/hosts")
f2 = open("/tmp/zj.txt")
shutil.copyfileobj(f1,f2)               #copy 文件对象
f1.close
f2.close

shutil.copyfile("/etc/hosts","/tmp/abcd.txt")        #copy文件名

shutil.copy("/etc/hosts","/tmp/aaa.txt")      #目标可能是目录
shutil.copy("/etc/passwd","/tmp/")

shutil.copy2("/etc/passwd","/tmp/")               #相当于cp -p 拷贝权限

shutil.copytree("/etc/security","/tmp/anquan")      #  cp -r

shutil.move("/tmp/zj.txt","/var/tmp/")                    #相当于mv

shutil.rmtree("/tmp/anquan")                                 #相当于rm -rf ,但只能删除目录不能删除单独文件
shutil.rmtree("/var/tmp/zj.txt")                                    # 不能删除单个文件
import os
os.remove("/var/tmp/zj.txt")                                           #这个可以删除单个文件

shutil.chown("/tmp/passwd",user="bob",group="bob")      #相当于chown

使用help可以查看更多
例: help(shutil.rmtree)


4. 变量赋值

Python支持链式多重赋值
x = y = 10
id(x)
9348224 #显示变量在内存的地址
id(y)
9348224
x = 20 #修改x = 20 x变了,y不变
y = 10 #y的值不变,数值是不可变的

a = b = [10,20]
a[0] = 100
a
[100,20]
b
[100,20] #列表是可变的


5. 多元赋值

a,b = 10,20 #相当于 a = 10;b = 20
a,b = b,a #a和b的值互换

——————————————————————————————————————————

6. 合法标识符

  1. 第一个字符必须是字母或下划线_
  2. 剩下的字符可以是字母和数字或下划线
  3. 大小写敏感区分

——————————————————————————————————————————

7. 关键字

['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue','def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is',
'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

练习:查看有哪些关键字

import keyword
print(keyword.kwlist)
keyword.iskeyword("len")   #判断len是否是关键字  或 "len"   in  keyword.kwlist 等等

——------------------------------------------------------------------------------------------

8. 内键

http://yiyibooks.cn/    -> python352文档 - > 库参考

9. 程序风格

编写程序时,应该建立一种统一且容易阅读的结构,并将它应用到每一个文件中去

#!/usr/bin/env python                      #起始行
"this is a test module"                     #模块文档字符串
import sys                          #导入模块
import osdebug = Ture                    #全局变量声明class FooClass(object):         #类定义"Foo class"pass def test():                           #函数定义"test function"foo = FooClass()if_name_ == '_main_':          #程序主体test()

10. 编写程序的流程、步骤

  1. 发呆、思考:在脑海里像过电影一样,想想程序是怎么进行的(交互的?非交互的?)
    交互的:考虑屏幕上提示什么,用户回答什么
  2. 思考程序有哪些功能。将这些功能创建函数,编写程序框架
import osdef get_fname():while True:fname = input("filename:")          if not os.path.exists(fname):         #判断文件是否存在  breakprint("文件已存在,请重试")return fname
def get_content():content = []while True:line = input('("end" to quit)>')if line == "end":breakcontent.append(line)return contentdef wfile(fname,content):with open(fname,"w") as fobj:fobj.writelines(content)if __name__ == '__main__':fname = get_fname()content = get_content()content = [line +"\n" for line in content]   #为每行加上回车wfile(fname,content)

#############################################################################################

11. 序列类型操作符


seq[ind] 获取下标为ind的元素 a = [“h”,“e”,“l”,“l”,“o”] a[3] = l
seq[ind1:ind2] 获取下标从ind1到ind2间的元素集合 a = [“h”,“e”,“l”,“l”,“o”] a[2:4] = [“l”,“l”]
seq*expr 序列重复expr次 print(“#”*5) 得到 #####
seq1+seq2 连接序列seq1和seq2 拼接(同类型) “abc”+“123” 或者

例:
“abc” +[10,20] 不可以不同类型 修改为 [“abc”] +[10,20]
obj in seq 判断obj元素是否包含在seq中
obj not in seq 判断obj元素是否不包含在seq中

12. 内建函数(工厂函数)


函数 意义
list(iter) 把可迭代对象转换为列表
str(obj) 把obj对象转换成字符串
tuple(iter) 把一个可迭代对象转换成一个元组对象
len(seq) 返回seq的长度
max(iter,key=None) 返回iter中的最大值
enumerate (枚举) 接受一个可迭代对象作为参数,返回一个enumerate对象 返回是元组
reversed(seq) (翻转) 接受一个序列作为参数,返回一个以逆序访问的迭代器
sorted(iter) (排序) 接受一个可迭代对象作为参数,返回一个有序的列表
------------------------------------------
list(10)          #无法装列表。数字无法转list("hello")    #列表
#结果得到 ["h","e","l","l","o"]list(("hello","world"))
["hello","world"]

str(obj)           #字符串
str(10)
"10"

tuple(iter)       #元组
tuple(abc)
("a","b","c")

a = "hello"
len(a)  得到5

names = ["bob","alice","tom"]
max(name)    得到tom   按第一个字母排序
min(names)    得到alice

hi = "hello"
alist = [10,20,30]for ind in range(len(hi)):print(ind,hi[ind])for item in enumerate(alist):print(item)for ind,val in enumerate(alist):print(ind,val)

print(list(reversed(alist)))  #翻转
for i in reversed(alist)print(i)print(sorted(alist))   #排序

13. 字符串操作符

比较操作符:字符串大小按 ASCII码值大小进行比较
切片操作符:[]、[:] 、[::]
成员关系操作:in 、not in

———————————————————————————————————————————

14. 检查标识符

  1. 程序接受用户输入
  2. 判断用户输入的标识符是否合法
  3. 用户输入的标识符不能使用关键字
  4. 有不合法字符,需要指明第几个字符不合法
import keyword
import stringfirst_chs = string.ascii_letters+"_"
other_chs = first_chs+string.digits
def check_id(idt):if keyword.iskeyword(idt):return "%s是关键字" %idtif idt[0] not in first_chs:return "首字符不合法"for ind,ch in enumerate(idt[1:]):if ch not in other_chs:return "第%s个字符不合法" %(ind+2)return "%s是合法的标识符" %idtif __name__ == '__main__':idt = input("请输入字符串:")print(check_id(idt))

15. 字符串格式化

%c
%s         #优先用str()函数进行字符串转换
%d /%i     #转成有符号十进制数
%#o        #转成无符号八进制数
%#x        #转成无符号十六进制数
%e /%E     #转成科学计数法
%f /%F      #转成浮点数
%10s%10s    #填充格式
%-10s%-10s   #左对齐
"" %()
print("%s" % a)"%s: %s" % ("bob",22)      #%s  / %d   常用
"%s: %d" % ("bob",22)
"97 is %c" % 97              #  %c转换数字成为对应的ASCII码,
"97 is %#o" % 97             #不常用
"97 is %#x" % 97               #不常用
"10000 is %e "  %10000         #不常用
"10/3 is %f"  %(10/3)                #不常用"%10s%10s" % ("name","age")    #常用,定义字段宽度为10个字节
"%-10s%-10s"  % ("name","age")   #常用,左对齐

16. format函数

(功能和上面%字符串格式化一样)

使用位置参数

-  "my name is{},age{}" .format("hoho",18)

使用关键字参数

- "my name is {name},age is {age}".format({"name":"bob","age":23})

填充与格式化

-{:[填充字符][对齐方式<^>][宽度]}
使用索引

- "name is {0[0]} age is {0[1]}" .format(["bob",23])"{}: {}" .format("bob",22)
"bob: 22""{1}: {0}" .format("bob",22)
"bob: 22""{0[1]}: {0[0]}" .format([22,"bob"])

练习:创建用户(Linux系统运行)

  1. 编写一个程序,实现创建用户的功能
  2. 提示用户输入
  3. 随机生成8位密码
  4. 创建用户并设置密码
  5. 将用户相关信息写入指定文件

参考代码

import sys
import subprocess
#import randpass
import random
import string
all_chs = string.ascii_letters+string.digits
def adduser(username,password,fname):info = """用户信息:
用户名:%s
密码:%s
""" %(username,password)subprocess.call("useradd %s" % username,shell=True)subprocess.call("echo %s |passwd --stdin %s" %(password,username),shell=True)with open(fname,"a") as fobj:fobj.write(info)def randpass(n=8):  #创建随机8位密码result=""for i in range(n):ch=random.choice(all_chs)result+=chreturn resultif __name__ == '__main__':password = randpass()fname = "/tmp/mima.txt"adduser(sys.argv[1],password,fname)

17. 原始字符串操作符

.原始字符串操作符是为了对付那些在字符串中出现的特殊字符
.在原始字符串里,所有的字符都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符

例:

 winPath = "c:\windows\new\temp" print(winPath)                # \t 成为tab   \n成为回车
c:\windows
ew  emp
newPath = r"c:\windows\temp"     #  r表示真实字符串`原始字符串 print(newPath)
c:\windows\temp newPath      #看到Python是如何存储的 其实 r 是加多\
c:\\windows\\temp

——————————————————————————————————————

18. 字符串内建函数 (字符串操作)

string.capitalize():   # 把字符串的第一个字符大写
string.center(width)  #返回一个原子符串居中,并使用空格填充至长度width 的新字符串
string.count(str,beg=0,end=len(string))  #返回str在string里面出现的次数,如果beg或者end指定则返回指定范围内str出现的次数
string.upper()                 #字符串变大写
string.strip()                   #删除两端空白字符,
string.lstrip()                   #删除左边空白字符
string.rstrip()                   #删除右边空白字符
string.lower()                    #字符串变小写
string.startswith("he")           #是以he开头吗
string.endswith("abc")           #是以abc结尾吗
string.replace("l","m")           #  l 替换为m
string.ljust(50,"*")              #  宽度为50,左边对齐,空格补充为*
string.rjust(50,"*")                #宽度为50,右边对齐,空格补充为*
string.isdigit()                      #判断字符串是不是全部数字
string.islower()                       #判断是否全部小写
string.isupper()
string.isidentifier()               #判断是否符合合法标识符

19. 字符串方法

"     hello world    ".strip()       #删除两端空白字符hi = "hello world"
hi.upper()                      #字符串变大写
hi.lower()                       #字符串变小写
hi.startswith("h")           #以h开头吗?
hi.startswith("he")
hi.endswith("abc")         #以abc结尾吗?
hi.replace("l","m")         #替换
hi.center(50)                #居中
hi.center(50,"*")
hi.ljust(50,"*")
hi.rjust(50,"*")
"1234".isdigit()                 #判断是否是数字
True
"hao123".isdigit()
False
"hao123".islower()      #是否小写

————————————————————————————————————————————

20. 创建及访问列表(列表list操作)

·列表是有序、可变的数据类型
·列表中可以包含不同类型的对象
·列表可以由 [ ] 或工厂函数创建
·支持下标及切片操作

20. 列表内建函数

列表方法 操作
list.append(obj) 向列表中添加一个对象
list.count(obj) 返回一个对象obj在列表中出现的次数
list.extend(seq) 把序号seq的内容添加到列表中
list.index(obj) 返回obj对象的下标
list.insert(index,obj) 在索引量为index的位置插入对象obj
list.reverse() 原地翻转列表
alist = [10,20,30,"bob","alice"]
alist.remove("bob")          #删除第一个bob
alist.append("25")            #添加一个对象
alist.sort()                  #排序升序
alist.reverse()                #翻转
alist.pop()                     #默认删除最后一项
alist.pop(1)                    #弹出
alist.insert(1,50)              #在下标为1的位置插入50
alist.extend([200,10,39])       #扩展列表
alist.extend("abc")              #会把abc 分开加到列表
alist.append("abc")              #注意和extend的区别
alist.index(50)                  #获取50的下标,没有50这个元素则报错

————————————————————————————————————————

atuple = (10,20,30,[1,2,3])
atuple.count(20)                  #统计有多少个20
atuple.index(20)                   #第一个20的下标
atuple[-1].append(4)            #理解即可,很少有应用

21. 单元素元组必须有逗号,否则不表示元组

a= (10)len(a)               #报错type(a)        #整数a =(10,)   #元组必须有逗号
len (a)
1
type(a)

练习: 用列表构建栈结构

  1. 栈是一个后进先出的结构
  2. 编写一个程序,用列表实现栈结构
  3. 需要支持压线、出栈、查询功能

参考代码

stack = []                    #全局变量从定义开始一直到程序结束,任何地方都可见、可用
def push_it():item = input("数据").strip()if item:stack.append(item)def pop_it():if stack:print("从栈中弹出了%s" % stack.pop())else:print("\033[32;1m空栈\033[0m")def view_it():print("\033[31;1m%s\033[0m" % stack)def show_menu():cmds = {"0": push_it,"1":pop_it,"2":view_it}prompt = """(0)压栈
(1)出栈
(2)查询
(3)退出
请选择(0/1/2/3)"""while True:choice = input(prompt).strip()[0]if choice not in "0123":print("无效输入,请重试")continueif choice == "3":print("Bye-bye")breakcmds[choice]()if __name__ == '__main__':show_menu()

##############################################################################################

22. 字典和集合/文件系统

  1. 写入字典
adict = {"name":"bob","age"20}
dict = (["ab","cd",("name","niu")])
{}.fromkeys(["niu","wang","li"],"male")
  1. 查询字典
    判断代码
20 in adict
False
"age" in adict
True

查询代码

for key in adict:print("%s:%s" % (key,adict[key)]))
print("%(name)s is %(age)s years old" %adict)

练习:通过key更新字典

通过key更新字典,如果key不在字典中则增加新增,在字典中则修改**

adict["email"] = "bob@tudu.cn"
print(adict)
{'name': 'bob', 'age': 20, 'email': 'bob@tudu.cn'} adict["age"] = 22
print(adict)
{'name': 'bob', 'age': 22, 'email': 'bob@tudu.cn'}

adict.keys()     #查询key的值或 直接adict for key in adict.keys():print(key)

或者

for key in adit:print(key)
list(adict.values())for key,val in adict.items():print("%s: %s" % (key ,val) )

23. 字典内建方法

dict.copy()
dict.get(key,default = none)
dict.items()
adict[phone]                    #没有会报错
adict.get("phone")                #没有指定则none 获取key为phone的值  ,重点
adict.get("phone","110")            #获取key为phone的值,没有返回110
adict.popitem()                     #随机弹出一项
adict.pop("email")                   #弹出key是email的项
adict.update({"aaa":100,"bbb":200})
print(adict.get("phone") )            #获取获取key为phone的值

24. Windows文本换行和Unix转换

要把Unix 文档换行转为windows文本换行,>>>> 使用命令Unix2dos  文件名
要把windows 文档换行转为Unix文本换行,>>>> 使用命令dos2Unix  文件名

————————————————————————————————————————

练习:编写类进度条程序

  1. 在屏幕上打印20个#号
  2. 符号@从20个#号穿过
  3. 当@符号到达尾部,再从头开始
import time
import sys
n = 0
print("#"*19,end="")
b = "\033[32;1m@\033[0m"
while True:print("\r%s%s%s" % ("#"*n,b,"#"*(19-n)),end="")     # \r 回车不换行 sys.stdout.flush()                    # 立即在屏幕上输出,不要放到缓冲区n+= 1time.sleep(0.3)if n == 20:n = 0

——————————————————————————————————————————

25. 集合

集合 :由不同元素组成的set,元素只能是不可变对象。相当于是无值的字典

集合类型操作符
集合支持用in 和not in 操作符检查成员
能够通过len() 检查集合大小
能够使用for 迭代集合成员
不能去切片,没有键

len(aset)
4
for ch in aset:print(ch)打印结果:
l
e
o
h

26. 集合类型操作符

** | 联合,取并集
& 交集

  • 差补**

bset = set("how")
aset = set("hello")
aset
{"h","o","l","o"}
bset
{"h","w","o"}
aset | bset     #并集
{"w","e","h","aset+bset      # 报错aset & bset     #交集
{"h","0"}aset - bset     #差补,aset中有,bset中没有的元素

27. 集合内建方法

set.add() 添加成员
set.update() 批量添加成员
set.remove() 移除成员

实操

aset = set("hello")
aset.add("new")
aset
{"h","o","l","e","new"}aset.update("new")
aset
{"h","o","l","e","new","n"}aset.update(["hello","world"])
aset
{"h","o","l","e","new","n","hello","wolrd"}aset.remove("n")
aset
{"h","o","l","e","new","hello","wolrd"}cset = set("ho")
cset.issubset(aset)               #cset 是aset的子集吗
aset.issuperset(cset)            # aset 是cset的超集吗
aset.intersection(bset)          #aset & bset    交集
aset.union(bset)                  #aset | bset      并集
aset.difference(bset)             #aset - bset    补差

cp /etc/passwd /tmp/
cp /etc/passwd /tmp/mima

修改mima,使之与passwd不完全一样

with open("/tmp/mima")  as f:aset = set(f)
with open("/tmp/passwd") as f:bset = set(f)
with open("/tmp/result.txt","w") as f:f.wirtelines(aset - bset)

六、简单模块

1. time 模块

导入方式:
import time

常用方法
time.time() # 返回时间戳 ,自1970-1-1 0:00:00 到执行命令期间的秒数 (常用)
time.ctime() #当前日期、时间 (常用)
time.localtime() #返回九元组格式时间
time.sleep(3) #睡眠3秒 (常用)
time.strftime(“%Y-%m-%d %H:%M:%S”)

2. datetime模块

导入方式:
import datetime

实操:

from datetime import datetime ,timedelta
t1 = datetime.now()      #把当前时间转换成时间对象
t1.year
t1.month
t1.day
t1.hour
t1.minute
t1.second
t1.microsecond
t2 = datetime(2018,10,10)#转换字符串为datetime对象
t1 = datetime.strptime("Dec 12 2018","%b %d %Y")
t = datetime(2018,12,10)
t1>tt = datetime.now()
days = timedelta(days = 100)
t1 = t -days
t2 = t +days

3. 异常

当程序运行时,因为遇到未解的错误而导致中止运行,便会出现traceback消息,打印异常

异常 描述
NameError 未声明/初始化对象
IndexError 序列中没有没有此索引
SyntaxError 语法错误
KeyboardInterrupt 用户中断执行
EOFError 没有内建输入,到达EOF标记
IOError 输入/输出操作失败

参考代码

try:num=int(input("number:"))          #把有可能发生异常的语句放到try中result=100/numprint(result)
except (ValueError,ZeroDivisionError):       #捕获异常print("无效输入,必须输入非0数字")
except (KeyboardInterrupt,EOFError):print("\nBye-bye")else:print(result)             #异常不发生才执行的语句,放到else中
finally:print("DONE")         #不管是否发生异常都要执行的语句,放到finally中

异常处理 try - except 和try - finally

这两种组合用的比较多


def set_age(name,age):if not 0<age<150:raise ValueError("年龄超过范围了(1-150)")print("%s现在是%s岁了" %(name,age))def set_age2(name,age):assert 0<age<150,"年龄超过范围了(1-150)"print("%s现在是%s岁了" %(name,age))if __name__ == '__main__':set_age("大牛",22)set_age2("神通",255)

#############################################################################################

4. OS模块

对文件系统的访问大多通过Python 的os模块实现
该模块是Python访问 —> 操作系统功能的主要接口
有些方法
如copy等,并没有提供,可以使用shutil模块作为补充


函数 作用
os.symlink() 创建符号链接(软连接)
os.listdir() 列出指定目录的文件
os.getcwd() 返回当前工作目录
os.mkdir() 创建目录
os.chmod() 改变权限模式
os.getatime() 返回最近访问时间
os.chdir() 改变工作目录
os.remove 删除文件(只能删除文件和空目录)
os.rmdir 删除空目录
os.rmtree
os.rename 重命名

参考代码

 **import os**                             **相当于Linux命令**
os.getcwd()                            #pwd
os.mkdir("/tmp/demo")          #mkdir  /tmp/demo
os.chdir("/tmp/demo")            #cd   /tmp/demo
os.listdir()                                 # ls
os.listdir("/home")                      #ls /home
os.mknod("mytest.txt")                 # touch  mytest.txt
os.symlink("/etc/hosts","zhuji")      #ln -s /etc/hosts   zhuji
os.unlink("zhuji")                            #删除软连接
os.chmod("mytest.txt")                    #touch   mytest.txt
os.rename("mytest.txt","test.doc")      #mv  mytest.txt   test.doc
os.remove("zhuji")                                # rm -f    zhuji
os.rmdir("/tmp/devops")                        #删除空目录
os.path.basename("/etc/sysconfig/network")       #从/etc/sysconfig 切割network
os.path.dirname("/etc/sysconfig/network")            #目录名称
os.path.join("/etc/sysconfig","network")
os.path.isfile("/etc/hosts")                         #是一个文件吗
os.path.isdir("/etc/hosts")                      #是一个目录吗
os.path.exists("/etc/hosts")                      #是否存在
os.path.islink("/etc/hosts")                         #是链接吗

5. pickle存储器

普通的文件只能把字符类型数据写入到文件中,pickle可以把任意类型的数据存储到文件中,
将来还能无损地取出。

f = open("/tmp/mydata","w")
f.write("hello world!\n")
f.write(100)                #不允许写入数字
f.write({"name:"bob"})      #不允许写入字典
f.close()

import pickle as p           #导入模块时,为其取别名p
f = open("/tmp/data","wb")
adict = {"name":"bob","age":23}
p.dump(adict,f)              #将字典存入文件
f.close()

import pickle as p
f = open("/tmp/data","rb")
mydict = p.load(f)        #加载赋值
f.close()

################################################################################################

练习:记账程序

  1. 假设在记账时,有一万元钱
  2. 无论是开销还是收入都要进行记账
  3. 记账内容包括时间、金额和说明等
  4. 记账数据要求永久存储

参考代码

  import os
import pickle
import timedef cost(record):amount = int(input('金额:'))comment = input('备注:')date = time.strftime('%Y-%m-%d')with open(record, 'rb') as fobj:data = pickle.load(fobj)balance = data[-1][-2] - amountdata.append([date, 0, amount, balance, comment])with open(record, 'wb') as fobj:pickle.dump(data, fobj)def save(record):amount = int(input('金额:'))comment = input('备注:')date = time.strftime('%Y-%m-%d')with open(record, 'rb') as fobj:data = pickle.load(fobj)balance = data[-1][-2] + amountdata.append([date, amount, 0, balance, comment])with open(record, 'wb') as fobj:pickle.dump(data, fobj)def query(record):print('%-12s%-10s%-10s%-10s%-20s' % ('date', 'save', 'cost', 'balance', 'comment'))with open(record, 'rb') as fobj:data = pickle.load(fobj)for item in data:print('%-12s%-10s%-10s%-10s%-20s' % tuple(item))def show_menu():record = r'D:\a\record.data'if not os.path.exists(record):init_data = [[time.strftime('%Y-%m-%d'), 0, 0, 10000, '开始记账'],]with open(record, 'wb') as fobj:pickle.dump(init_data, fobj)cmds = {'0': cost, '1': save, '2': query}prompt = """(0) 记录开销
(1) 记录收入
(2) 查询收支
(3) 退出
请选择(0/1/2/3): """while True:try:choice = input(prompt).strip()[0]except IndexError:continueexcept (KeyboardInterrupt, EOFError):choice = '3'if choice not in '0/1/2/3':print('无效输入,请重试')continueif choice == '3':print('\nBye-bye')breakcmds[choice](record)if __name__ == '__main__':show_menu()

七、函数应用

1. 函数定义

def foo():print("in foo")boo()    #可以先使用再定义def boo():print("in boo")foo()
foo     #function foo at 0x7f18ce311b18def get_age(name,age):print("%s is %s years old." % (name,age))

2. 函数操作符

使用一对圆括号() 调用函数,如果没有圆括号,只是对函数的引用
任何输入的参数都必须放置在括号中

操作
get_age() #error 没有加参数
get_age(“bob”,25,26) #error
get_age(“bob”,25) #正确
get_age(25,“bob”) #语法没有错误,语义不对
get_age(age = 25,name = “bob”) #正确
get_age(age = 25, “bob”) #语法错误,key = val 形式必须在后
get_age(25,name = “bob”) #错误,name得到多个值
get_age(“bob”,age = 25) #正确


2. 参数组

Python允许程序员执行一个没有显式定义参数的函数
相应的方法是通过一个把元组(非关键字参数)或字典(关键字参数)作为参数数组传递给函数

def myfunc(*args):       #    *标识args 是个元组print(args)def myfunc2(**kwargs):    #  **标识kwargs 是字典print(kwargs)if __name__ == '__main__':myfunc()                      #得到  () myfunc(10)                    #得到 (10,)myfunc(10,20,30)              # 得到 (10, 20, 30)myfunc(10,20,30,"bob","tom")  #得到 (10, 20, 30, 'bob', 'tom')myfunc2(name="bob")          #得到 {'name': 'bob'}myfunc2(name="bob",age="23")   #得到  {'name': 'bob', 'age': '23'}

def add(x,y):print(x+y)if __name__ == '__main__':alist = [10,20]add(*alist)      #调用函数时,参数加上 * 表示将序列对象拆开add(*"ab")        #将字符串拆开

练习:简单的加减法数学游戏

  1. 随机生成两个100以内的数字
  2. 随机选择加法或是减法
  3. 总是使用大的数字减去小的数字
  4. 如果用户错三次,程序给出正确的答案

import randomdef add(x,y):return x +ydef sub(x,y):return x - ydef exam():cmds = {"+":add,"-":sub}
#cmds = {"+":lambda x,y:x+y,"-":lambda x,y:x-y}        #使用这个lambda可以忽略两个函数add和subnums = [random.randint(1,100) for i in range(2)]nums.sort(reverse=True)    #降序排列op = random.choice("+-")prompt = "%s%s%s=" % (nums[0],op,nums[1])# if op == "+":#     result = nums[0] + nums[1]# else:#     result = nums[0] - nums[1]result = cmds[op](*nums)tries = 0while tries <3:try:answer=int(input(prompt))except (ValueError,UnboundLocalError):print("请输入数字")continueif answer == result:print("very good")breakelse:print("答错了")tries +=1else:print("%s%s" %(prompt,result))if __name__ == '__main__':while True:exam()try:yn=input("continue(y/n|Y/N)").strip()[0]except IndexError:continueexcept (KeyboardInterrupt,EOFError):yn="n"if yn in "Nn":print("Bye-bye")brea

4. lambda 匿名函数

Python额允许用lambda 关键字创造匿名函数
匿名是因为不需要以标准的def 方式来声明
一个完整的lambda “语句” 代表了一个表达式,这个
表达式的定义体 必须和声明放在同一行

格式 lambda [arg1,[arg2,…argN]] : expression

a =lambda x,y :x+y
print(a(3,4))
7

常规

def  add (x,y)return x +y
add(10,20)
30

lambda函数

myadd = lambda x,y :x+y
myadd(10,20)
30

——————————————————————————————————————

5. filter 函数

filter(func,seq) :调用一个布尔函数 func来迭代遍历每个序列中的元素;
返回一个使func返回值为true的元素的序列
.如果布尔函数比较简单,直接使用lambda匿名函数就显得非常方便了

data = filter(lambda x :x %2,[num for num in range(10)])
print(data)                     #过滤出10以内的奇数
[1,3,5,7,9]

from random import randintdef func1(n):return n %2if __name__ == '__main__':numbs = [randint(1,100) for i in range(10)]print(numbs)print(list(filter(func1,numbs)))print(list(filter(lambda n:n%2,numbs)))   #效果一样  可以省略def func1(n)

打印结果:
[29, 82, 30, 10, 60, 15, 100, 93, 88, 66]
[29, 15, 93]


6. map 函数

from random import randintdef func1(n):return n %2if __name__ == '__main__':numbs = [randint(1,100) for i in range(10)]print(numbs)print(list(filter(func1,numbs)))print(list(filter(lambda n:n%2,numbs)))  print(list(map(func2,numbs)))         #加工一下print(list(map(lambda n:n+1,numbs)))  #组合lambda 使用

##################################################################################################

八、函数高级应用

1. 变量作用域

全局变量 # 从定义开始到程序结束
局部变量 #函数内的变量是局部变量,局部变量当函数调用结束后就消失
global语句 # 局部改变全局的值,
名字空间 # 名字空间,标识符搜索顺序依次是 局部 、全局、和内建

如果两个函数中有同名变量,两个同名变量没有关系
局部变量不会改变全局变量的值
函数作用域 —> 局部 、全局、内建 依次搜索

x = 10
def test2(): global   x      #声明这里的  x 是全局变量 xx = "zhangsan"print(x)
test2()

打印结果:
zhangsan #改变了原本全局变了 x =10

————————————————————————————————————————————

2. 函数式编程

四种形式

  1. 偏函数
  2. 递归函数
  3. 生成器
  4. 普通函数
def add(a,b,c,d):return a+b+c+d
add(10,20,30,40)
add(10,20,30,123)                                    #每次10,20,30 都没有改变可以改以下偏函数

3. 偏函数

相当于是改造现有函数,将其一部分参数固定下来

from functools import partial myadd = partial(add,10,20,30)myadd(5)                                                    #得到是10+20+30+5 的值from operator import add
from functools import partial
add10 = partial(add,10)
print(add10(25))                                       #得到10+25
35

import tkinter
from functools import partialroot = tkinter.Tk()    #相当于创建一个窗体
lb =tkinter.Label(root,text="hello world",font="arial 20")
b1 = tkinter.Button(root,bg="blue",fg="white",text="Button 1")
mybutton = partial(tkinter.Button,root,bg="blue",fg="white")       #使用偏函数
b2 = mybutton(text="Button 2")
b3 = mybutton(text="Button 3")
b4 = mybutton(text="Quit",command=root.quit)
for item in [lb,b1,b2,b3,b4]:item.pack()root.mainloop()

————————————————————————————————————

4. 递归函数

如果函数包含了对其自身的调用,该函数就是递归的在操作系统中,
查看某一目录内所有文件、修改权限等都是递归的应用

def func1(n):if n == 1:return 1return n *func1(n-1)# 5* func(4)#5*4*func(3)
if __name__ == '__main__':print(func1(5))

from random import randintdef quick_sort(seq):if len(seq)<2:return seqmiddle = seq[0]smaller = []larger = []for item in seq[1:]:if item<middle:smaller.append(item)else:larger.append(item)return quick_sort(smaller) +[middle]+quick_sort(larger)
if __name__ == '__main__':nums = [randint(1,100) for i in range(10)]print(nums)print(quick_sort(nums))

5. 生成器

从句法上讲,生成器是一个带yield语句的函数
一个函数或者子程序只返回一次,但一个生成器能暂停执行并返回一个中间的结果
yield语句返回一个值给调用者并暂停执行
当生成器的 next() 方法被调用的时候,它会准确地从离开地方继续

生成器
本质上是函数,但是它能生成多个中间值,而函数只有一个最终值
生成器节省内存,更加有效率

ips = ["192.168.1.%s" %i for i in range(1,255)]    #方括号是生成列表
print(ips)
hosts = ("192.168.1.%s" %i for i in range(1,255))  #圆括号变成生成器
print(hosts)     #得到 <generator object <genexpr> at 0x000001A07F3CBCC8>
for host in hosts:print(host)

生成器通过yield生成多个中间结果

def mygen():yield 100print("-------------------")yield 200print("####################")yield 300
a = mygen()
a.__next__()            #得到100
a.__next__()               #得到200
x = a.__next__()           #赋值给x
x                                #得到300
a.__next__()                   #没有数据将会抛出StopIteration 异常,生成器对象是一次性的for item in b:           #for 可以遍历生成器,遇到StopIteration 自动停止print(item)

生成器练习:每次获取文件10行数据

参考代码:

def file_block(fobj):content = [ ]for line in fobj:content.append(line)if len(content) == 10:        # 10行生成一次  yield contentcontent.clear()               #生成数据交给使用者用清空,以便存 下10行               if content:                      #如果循环结束后还有数据,生成最后不到10行的内容                        yield contentif __name__ == '__main__':fname = "/etc/passwd"fobj = open(fname)for block in file_block(fobj):print(block)fobj.close()

6. 内部函数

  1. 闭包
  2. 闭包实例
  3. 装饰器

——————————————————————————————————————————

7. 闭包

闭包将内部函数自己的代码和作用域以及外部函数的作用结合起来
闭包的词法变量不属于全局名字空间域或者局部的–而属于其他的名字空间,带着"流浪"的作用域
闭包对于安装计算,隐匿状态,以及在函数对象和作用域中随意地切换时很有用的
闭包也是函数,但是他们能携带一些额外的作用域


闭包练习:–>创建通用的计数器

import tkinter
from functools import partialdef pstar():print("*"*30)#def hello():
#lb.config(text="Hello China")
#def welcome():               #使用了say_hi 代替
#lb.config(text="hello TEDU")def say_hi(word):def greet():lb.config(text="Hello %s" % word)return greetroot=tkinter.Tk()         #相当于创建一个窗体
lb = tkinter.Label(root,text="Hello World!",font="Arial 20")
MyButton = partial(tkinter.Button,root,bg="blue",fg="white")
b1 = MyButton(text="Button 1",command=pstar)
b2=MyButton(text="Button 2",command=say_hi("China"))    #使用闭包函数
b3=MyButton(text="Button 3",command=say_hi("Tedu"))
b4=MyButton(text="Quit",command=root.quit)
for item in [lb,b1,b2,b3,b4]:item .pack()root.mainloop()

————————————————————————————————————————

8. 装饰器

装饰器是在函数调用之上的修饰
这些修饰仅是当声明一个函数或者方法的时候,才会应用的额外调用
使用装饰器的情形有:
-引入日志
-增加计时逻辑来检测性能
-给函数加入事务的能力


def set_color(func):def set_red():return "\033[31;1m%s\033[0m" % func()return set_red()def hello():return "Hello World"@set_color                 #装饰器使用
def welcome():return "Hello China"@set_color
def mytest():a = 10+10return aif __name__ == '__main__':# print(hello())# print(welcome())hello = set_color(hello)print(hello())print(welcome())print(mytest())

######################################################################################

九、什么是模块

模块支持从逻辑上组织Python代码
当代码量变得相当大的时候,最好把代码分成一些有组织的代码段
代码片相互间有一定的联系,可能是一个包含数据成员和方法的类,
也可能是一组相关但彼此独立的操作函数
·这些代码段是共享的,所以Python允许“调入”一个模块,
允许使用其他模块的属性来利用之前的工作成果,实现代码重用


模块文件
·说模块是按照逻辑来组织Python代码的方法,文件是物理层上组织模块的方法
一个文件被看作是一个独立模块,一个模块也可以被看作是一个文件
模块的文件名就是模块的名字加上扩展名.py


名称空间
·名称空间就是一个从名称到对象的关系映射集合
·给定一个模块名之后,只可能有一个模块被导入到Python解释器中,
所以在不同模块间不会出现名称交叉现象
·每个模块都定义了它自己的唯一的名称空间


1. 模块导入方法

四种方式

  1. 使用import导入模块
  2. 可以在一行导入多个模块,但是可读性会下降
import time,os,sys     #不推荐推荐,每行导入一个模块
  1. 可以只导入模块的某些属性
from random import choice ,randint  #只导入单个模块,常用
  1. 导入模块时,可以为模块取别名
import pickle as p     #取别名  ,不太常用

pycharm 可以点code -> optimize import可以优化导入模块(没有用到的模块将会被
移除,导入的模块按字母顺序排序)

导入模块时,Python会到这些位置搜索:

  1. sys.path 定义的路径
  2. 环境变量PYTHONPATH定义的路径
    #export PYTHONPATH = /var/… (路径)

当导入模块时,模块的顶层代码会被执行
一个模块不管被导入(import) 多少次,只会被加载(load)一次

导入包
包是一个有层次的文件目录结构,为平坦的名称空间加入有层次的组织结构
允许程序员把有联系的模块组合到一起
python2.7 中 包目录下必须有一个_init_.py文件
在Python中,目录可以当成特殊的模块,叫作包,导入mods 目录中的hello.py文件可以为

例如

mkdir mods
vim  mods/hello.py
hi = "hello world"import mods.hello
mods.hello.hi
from mods.hello import hi
from mods import hello
hello.hi

2. hashlib 模块

hashlib 用来代替md5和sha模块,并使他们的API一致,专门提供hash算法
包括 md5 、sha1、 sha224、 sha256、 sha384 、sha512,使用非常简单方便

加密
- 对称加密 :加解密使用相同的算法和秘钥 DES/3DES/AES
- 非对称加密: 加解密使用不同的秘钥 RSA/DSA
- 单向加密: 加密只能向一个方向进行,不能通过结果反推回原始数据,MD3/SHA

单向加密用途

  1. 存储加密密码
  2. 校验文件的完整 http://www.cmd5.com/ 可以查询

hashlib:可用于计算MD5值


import hashlib
m = hashlib.md5(b"123456")   #接受二进制形式
print(m.hexdigest())
e10adc3949ba59abbe56e057f20f883e

文件生成MD5

with open("/etc/passwd","rb") as fobj:data = fobj.read()m = hashlib.md5(data)
print(m.hexdigest())

————————————————————-----
MD5检测

import sys
import hashlib
def check_md5(fname):m = hashlib.md5()with open(fname,"rb") as fobj:while True:data = fobj.read(4096)if not data:breakm.update(data)return m.hexdigest()if __name__ == '__main__':print(check_md5(sys.argv[1]))

###############################################################################################

3. tarfile模块

tarfile 模块允许创建、访问tar文件
同时支持 gzip 、bzip2格式

tarfile: 实现压缩、解压缩、可以调用gzip 、bzip2等


import tarfile
import os
tar = tarfile.open("/tmp/security.tar.gz","w:gz")
os.chdir("/etc")
tar.add("security")
tar.close()os.mkdir("/tmp/demo")
tar = tarfile.open("/tmp/security.tar.gz","r:gz")
tar.extractall(path="/tmp/demo")
tar.close()

练习:备份程序

  1. 需要支持完全和增量备份
  2. 周一执行完全备份
  3. 其他时间执行增量备份
  4. 备份文件需要打包为tar文件并使用gzip格式压缩

构思——备份:

  1. 完全备份
    1)压缩整个目录
    2)计算每个文件的MD5值
  2. 增量备份
    1)取出前一天文件的md5值
    2)计算当前每个文件的md5值
    3) 新增文件和有变化文件需要备份
    4)更新MD5值

参考代码

from time import strftime
import os
import tarfile
import pickle
import hashlibdef check_md5(fname):m = hashlib.md5()with open(fname,"rb") as fobj:while True:data = fobj.read(4096)if not data:breakm.update(data)return m.hexdigest()#full_backup 完整备份
def full_backup(folder,dest,md5file):md5_dict = {}      #用于保存每个文件的MD5值{“文件绝对路径” :md5值}fname = os.path.basename(folder.rstrip("/"))fname = "%s_full_%s.tar.gz" % (fname,strftime("%Y%m%d"))fname = os.path.join(dest,fname)  #目标文件的绝对路径tar = tarfile.open(fname,"w:gz")   #压缩tar.add(folder)tar.close()for path,folders,files in os.walk(folder):for file in files:key = os.path.join(path,file)      #拼出绝对路径md5_dict[file] = check_md5(file)    #写入MD5字典with open(md5file,"wb") as fobj:          #字典写入文件pickle.dump(md5_dict,fobj)#增量备份
def incr_backup(folder,dest,md5file):md5_dict={}  # 用于保存每个文件的MD5值{“文件绝对路径” :md5值}fname=os.path.basename(folder.rstrip("/"))fname="%s_full_%s.tar.gz"%(fname,strftime("%Y%m%d"))fname=os.path.join(dest,fname)  # 目标文件的绝对路径for path,folders,files in os.walk(folder):for file in files:key = os.path.join(path,file)      #拼出绝对路径md5_dict[key] = check_md5(key)    #计算当前文件的md5值with open(md5file,"rb") as fobj:oldmd5 = pickle.load(fobj)      #取出前一天文件MD5值with  open(md5file,"wb") as fobj:pickle.dump(md5_dict,fobj)       #更新文件md5值tar = tarfile.open(fname,"w:gz")for key in  md5_dict:if oldmd5.get(key) != md5_dict[key]:tar.add(key)              #新文件,有变化文件进行备份tar.close()if __name__ == '__main__':folder = "/tmp/demo/security"dest = "/tmp/demo"md5file = "/tmp/demo/md5file"if strftime("%a") == "Mon":full_backup(folder,dest,md5file)else:incr_backup(folder,dest,md5file)

十、OOP(面向对象编程)

1. 基本概念

类(Class):
用来描述具有相同的属性和方法的对象的集合,它定义了该集合中每个对象所共有的属性和方法。对象是类的实例

实例化
创建一个类的实例,类的具体对象 。

方法
类中定义的函数

对象
通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。


2. 创建类

使用class 语句来创建一个新类,class之后为类的名称并以冒名结尾
类名建议使用驼峰形式

class BearToy:pass

游戏人物:
名字、职业、性别、装备、武器 、位置
跳、走、飞、攻击

OOP:面向对象的编程,实现属性和行为的融合统一
calss Hero:
name =
gender =
def run():
move


2. 子类

OOP的更强大方面之一是能够使用一个已经定义好的类,扩展它或者对其进行修改,而不会影响系统中
使用现存的其它代码片段
OOD(面向对象设计)允许类特征在子孙类或子类中进行继承

创建子类
创建子类只需要在圆括号中写明从哪个父类继承即可

class Vendor:def __init__(self,phone):self.phone = phonedef dial(self):print("calling %s" % self.phone)class BearToy:def __init__(self,size,color):"""实例化一个对象时,自动调用"""self.size = size                     #bear_big.size = "Large"self.color = color                 #bear_big.color = "Brown"self.vendor = Vendor("400-800-1234")      #一个类是另一个类的组件   def sing(self):print("my color is %s,lalala..." % self.color)class NewBearToy(BearToy):      #子类 括号中填入的是父类、基类def __init__(self,name,size,color):# BearToy.__init__(self,size,color): 和下面super功能一样其中一条都可以super(NewBearToy,self).__init__(size,color)self.name = name if __name__ == '__main__':# bear_big = BearToy("Large","Brown")    #实例化,bear_big自动作为第一个参数传递# vendor=Vendor("400-800-1234")# print(bear_big.vendor.phone)# bear_big.vendor.dial()# print(bear_big.size)# print(bear_big.color)# bear_big.sing()bear2 =NewBearToy("Middle","Brown")bear2.sing()

3. 多重继承

Python允许多重继承,即一个类可以是对个父类的子类,子类可以拥有所有的父类的属性

class Foo:def hello(self):print("hello world")class Bar:def welcome(self):print("how are you?")class FooBar(Foo,Bar):'子类有多个父类,它将继承所有父类的方法'pass

3. 静态方法

基本上就是一个函数
在语法上就像一个方法
没有访问对象和它的字段或方法
语法
使用staticmethod装饰器定义
@staticmethod

静态实例

class Book:def __init__(self,title,author):self.title = titleself.author = authordef __str__(self):return "<<%s>>" % self.titledef __call__(self):print("<<%s>>is written by %s. " % (self.title,self.author))if __name__ == '__main__':core_py = Book("Core Python","Wesley")print(core_py)        #调用 __str__方法print(core_py())     #调用__call__方法

4. 类方法

使用classmethod 装饰器定义
第一个参数cls 表示类本身

class Date:def __init__(self,year,month,day):self.year = yearself.month = monthself.day = day@classmethoddef create(cls,str_date):"类中的方法,没有实例不能直接调用,需要将其定义为类方法"year,month,day = map(int,str_date.split("-"))instance = cls(year,month,day)return instance@staticmethod    #静态方法def check_date(cls,str_date):"相当于和类没有关系,只是把一个函数放到类中"year,month,day=map(int,str_date.split("-"))return year<4000 and 1<=month<=12 and 1<=day
if __name__ == '__main__':d1 = Date(2019,12,15)print(d1.year)d2 = Date.create("2020-8-1")print(d2)

###############################################################################################

十一、 search 函数

import re
m = re.search("f..","seafood")
m.group()                                     #得到 foo

1. findall

re.findall("f..","seafood is food")    # 匹配所有 ,返回列表
["foo","foo"]

2. finditer

re.finditer("f..","seafood is food")        #不是直接返回列表,返回的是所有匹配对象的生成器

3. split

re.split("\.|-","hello-world.tar.gz")    # 以.和- 区分 字符串
["hello","world","tar","gz"]

4. sub

re.sub("n[a-z]me,"Niu","Hi name,Nice to meet you nbme!")
"Hi Niu, Nice to meet you Niu!""Hi name,Nice to meet you nbme!" .replace("name","Niu")   #用replace也可以替换

5. compile

在进行大量匹配的时候,先把模式pattern 编译一下,可以提升效率

patt = re.compile("f..")
m = patt.search("seafood")
m.group()

练习:分析Apache访问日志

编写一个Apache日志分析脚本

  1. 统计每个客户端访问Apache服务器的次数
  2. 将统计信息通过字典的方式显示出来
  3. 分别统计客户端是Firefox 和MSIE的访问次数
  4. 分别使用函数式编程和面向对象编程的方式实现
import re
def count_patt(fname,patt):cpatt = re.compile(patt)patt_dict = {}with open(fname) as fobj:for line in fobj:m = cpatt.search(line)if m:key = m.group()patt_dict[key] = patt_dict.get(key,0) +1return patt_dictif __name__ == '__main__':fname = r"D:\a\access_log"ip = "^(\d+\.){3}\d+"br = "Chrome|Firefox|MSIE"print(count_patt(fname,ip))print(count_patt(fname,br))

————————————————————————————————

import re
from collections import Counterclass CountPatt:def __init__(self,patt):self.cpatt = re.compile(patt)def count_patt(self,fname):# cpatt=re.compile(patt)# patt_dict={}result = Counter()with open(fname) as fobj:for line in fobj:m=self.cpatt.search(line)if m:key=m.group()result.update([key])# patt_dict[key]=patt_dict.get(key,0) + 1# return patt_dictreturn result
if __name__ == '__main__':fname=r"D:\a\access_log"ip="^(\d+\.){3}\d+"cp = CountPatt(ip)print(cp.count_patt(fname))

###############################################################################################

十二、 re模块(正则)

使用正则需要导入re模块

import re

1. 匹配单个字符

记号 说明
. 匹配任意字符(换行符除外)单单一个字符
[…x-y…] 匹配字符组里的任意字符
[^…x-y…] 匹配不在字符组里的任意字符
\d 匹配任意数字,与[0-9]同义
\D 匹配非数字
\w 匹配任意数字字母字符,与[0-9a-zA-Z]同义
\W 匹配非任意数字字母字符 --空格和符号
\s 匹配空白字符,与[\r\v\f\t\n] 同义
\S 匹配非空白字符

测试
在vim里面 输入 / 加内容 例如 /\D 匹配非数字
搜索tm字符内容

/t.m
/t[0-9a-z]m
/\W
/t[-a0]m
/t[0-9^]m   #和/t[^0-9]m   意义一样,取反

2. 匹配一组字符

记号 说明
literal 匹配字符串的值
re1 re2
* 匹配前面出现的正则表达式零次或多次
+ 匹配前面出现的正则表达式一次或多次
匹配前面出现的正则表达式零次或一次
{M,N} 匹配前面出现的正则表达式至少M次最多N次

例如:

/tam\|t8m
/t\{3,5\}m
/t\{3,\}
/t\?m
/t\+m

3. 其他元字符

记号 说明
^ 匹配字符串的开始
$ 匹配字符串的结尾
\b 匹配单词的边界
() 对正则表达式分组
\nn 匹配已保存的子组

4. 贪婪匹配

  • 和? 都是贪婪匹配操作符,在其后加上? 可以 取消其贪婪匹配行为
    正则表达式匹配对象通过groups函数 获取子组
data = "His phone number is : 150889912"
m = re.search(".+|(\d+\)",data)  #默认+ 或者 * 都是贪婪匹配
m.group()                         #总是返回整个模式匹配到的内容
"His phone number is : 150889912"
m.group(1)
"2"
m = re.search(".+?|(\d+\)",data)              #  ?  可以取消贪婪匹配
m.group()
"His phone number is : 150889912"
m.group(1)
"150889912"

————————————————————————————————————————

import re
re.match("f..","food")                             #如果匹配到,返回一个匹配对象
print(re.match("f","seafood"))             #没有匹配到,返回None
m = re.match("f..","food')
m.group()

###############################################################################################

十三、socket模块

1. 套接字

套接字是一种具有“通讯端点” 概念的计算机网络数据结构
家族名为 AF_UNIX
基于网络的 ,家族名 为 AF_INET

2. 面向连接与无连接

无论你使用哪一种地址家族,套接字的类型只有两种。

  1. 一种是面向连接的套接字
  2. 另一种是无连接的套接字

TCP
面向连接的主要协议就是传输控制协议TCP ,套接字类型为 SOCK_STREAM

UDP
无连接的主要协议是用户数据报协议UDP ,套接字类型为 SOCK_DGRAM

Python中使用socket模块中的socket函数实现套接字的创建

3. Python字符串str和bytes类型转换

Python中所有的字符有:str类型和bytes类型
str类型转换为bytes类型 ( encode 和 decode )

a = "你好"
type(a)
<class "str">
a.encode()                   #将str 转换为bytes
b'xe4\xbd\xa0\xe5\xa5\xbd'b = b"Hello"
tyep(b)
<class "bytes">
b.decode()                    #将bytes转换为str

3. TCP

面向连接的主要协议就是 传输控制协议 TCP ,
套接字类型: SOCK_STREAM

创建TCP服务器

创建TCP服务器的主要步骤如下:

  1. 创建服务器套接字:s = socket.socket()
  2. 绑定地址到套接字:s.bind()
  3. 启动监听:s.listen()
  4. 接受客户端连接:s.accept()
  5. 与客户端通信: recv()/send()
  6. 关闭套接字: s.close()

参考代码

import socket
host = ""                                                         #代表0.0.0.0
port = 12345                                                            #应该大于1024
addr = (host,port)
s = socket.socket()                                                            #默认使用TCP协议
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)  #设置套接字选项,使得服务程序结束后立即再启动
s.bind(addr)
s.listen(1)                                                                       #一般只能写到5以内,表示允许多少客户端排队访问
cli_sock,cli_addr = s.accept()
print("客户端:",cli_addr)
data = cli_sock.recv(1024)                                          #相当于fobj.read(1024)
print(data)
print(data.decode())
sdata = "欢迎!\r\n"
cli_sock.send(sdata.encode())                          #发送的数据必需是bytes类型,二进制
cli_sock.close()
s.close()

创建TCP客户端

创建TCP 客户端的步骤主要如下 :

  1. 创建客户端套接字:cs = socket.socket()
  2. 尝试连接服务器: cs=connet()
  3. 与服务器通信:cs.send()/cs.recv()
  4. 关闭客户端套接字:cs.close()

参考代码

import sockethost = "127.0.0.1"
port = "12345"
addr = (host,port)
c = socket.socket()
c.connect(addr)
c.send(b"Hello World!\r\n")
data = c.recv(1024)
print(data.decode(),end="")
c.close()

4. UDP

无连接的主要协议是用户 数据报协议 UDP ,
套接字类型: SOCK_DGRAM

创建UDP服务器

创建UDP服务器的主要步骤如下:

  1. 创建服务器套接字:s =socket.socket()
  2. 绑定服务器套接字:s.bind()
  3. 接收、发送数据: s.recvfrom()/ss.sendto()
  4. 关闭套接字: s.close()

参考代码

import sockethost = ""
port = 12345
addr = (host,port)
s = socket.socket(type=socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(addr)data,cli_addr = s.recvfrom(1024)
print(data.decode(),end="")
s.sendto(b"How are you?\r\n",cli_addr)
s.close()

创建UDP客户端

创建UDP客户端的步骤主要如下:

  1. 创建客户端套接字:cs = socket.socket()
  2. 与服务器通信: cs.sendto()/cs.recvfrom()
  3. 关闭客户端套接字:cs.close()

参考代码

import socket
host = ""
port = 12345
addr = (host,port)
c = socket.socket(type=socket.SOCK_DGRAM)c.sendto(b"Nice to meet you!\r\n",addr)
data,ser_addr = c.recvfrom(1024)
print(data.decode())
c.close()

UPD服务器循环

为了实现不间断接收信息

import sockethost = ""
port = 12345
addr = (host,port)
s = socket.socket(type=socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(addr)while True:data,cli_addr = s.recvfrom(1024)print(data.decode(),end="")s.sendto(b"How are you?\r\n",cli_addr)
s.close()

UDP客户端循环

import sockethost = ""
port = 12345
addr = (host,port)
c = socket.socket(type=socket.SOCK_DGRAM)while True:sdata = input(">")+"\r\n"if sdata.strip() == "quit":breakc.sendto(b"Nice to meet you!\r\n",addr)data,ser_addr = c.recvfrom(1024)print(data.decode())
c.close()

运维Python大全相关推荐

  1. 【分享】Oracle 常用运维命令大全

    教材下载 ORACLE OCP 19C 官方电子教材 ORACLE OCP 12C官方电子教材 课程介绍 DBA数据库管理必备认证:ORACLE OCP 19C Oracle 常用运维命令大全 一.o ...

  2. 华为防火墙查看日志命令_华为USG防火墙运维命令大全word精品

    华为 USG 防火墙运维命令大全 i 查会话 使用场合 针对可以建会话的报文,可以通过查看会话是否创建以及会话详细信息来确定报文是否正常通过防火墙. 命令介绍(命令类) display firewal ...

  3. python工作-Python自动化运维|Python语言工作岗位待遇如何?

    Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的Java语言,适合初学者的Basic语言,适合网页编程的Java语言等,Python是他们其 ...

  4. scrapy python3.8_银狐DevNet-网络运维Python初篇(四)netmiko抓取华为网络配置并存入本地...

    1.训练场景:读取excel中设备IP地址,通过Netmiko抓取设备配置,并存入本地 上一小节我们通过excel得到设备IP地址,并用Netmiko批量抓取设备配置并打印出来,真实运维场景我们需要把 ...

  5. Oracle DG日常运维命令大全

    作者:IT邦德 中国DBA联盟(ACDU)成员,目前从事DBA及程序编程 (Web\java\Python)工作,主要服务于生产制造 现拥有 Oracle 11g OCP/OCM. Mysql.Oce ...

  6. 【逗老师带你学IT】HUAWEI华为防火墙自动化运维Python ssh管理网络设备

    本文,介绍一种.通过Django框架,搭建API服务器,并通过此API服务器管理华为防火墙.并以此衍生出,通过Django+Python+ssh的方式管理网络设备的方法. 关于Django环境的搭建, ...

  7. 网络运维(Python自动化运维)考点

    考试题型 选择题 30 分 简答题 包含进程同步编程题 20 分 综合题 ansible 20 分 复习大纲 第 2 章 基础运维技能 (1)列举 3 种常用字符编码,简述怎样在 str 和 byte ...

  8. oracle 查看表被谁删了_【分享】Oracle 常用运维命令大全

    一.oracle建库与删库命令 (1)oracle11g建库(一般习惯配置gdbname与sid名一样,sys密码与system密码一样,以方便记忆) [oracledb@ ~]$ dbca -sil ...

  9. 自动化运维Python系列(六)之面向对象

    面向对象编程 面向过程:根据业务逻辑从上到下垒代码 函数式:将某功能代码封装到函数中,以后直接调用,不需要再次编写 面向对象:对函数进行分类和封装,让开发"更快更好更强..." # ...

  10. 自动化运维 python 批量监控服务器_1、python自动化运维——监测服务器状态

    监测服务器状态 获取系统性能信息 1.CPU信息: Linux操作系统的CPU利用的几个部分: User Time;SystemTime;Wait IO;Idle psutil.cpu_times() ...

最新文章

  1. 智能车竞赛技术报告 | 智能视觉组 - 大连海事大学 - 菜鸡啄米
  2. [原]android2.3如何使用SharedPreferences存储字符串集合类型的元素
  3. android时间显示中文版,系统运行时间显示工具(Vov System Uptime)
  4. 微服务架构(一):什么是微服务
  5. PVM的安装和编译PVM程序
  6. VTK:PolyData之SurfacePointPlacer
  7. 病毒源代码Java_病毒代码_bat病毒代码_java病毒代码(5)
  8. ios给系统添加分类管理属性
  9. js封装函数_JavaScript基础-如何封装函数来改变元素的位置
  10. java中不带package和带package的编译运行方式
  11. Spring web应用最大的败笔
  12. 伺服驱动器生产文件_直流伺服系统的组成和控制原理详解
  13. MySQL高级-MySQL查询缓存优化
  14. 问题六十八:着色模型(shading model)(1)——反射模型(reflection model)(2.1)——漫反射(diffuse reflection)
  15. JAVA-数据库之MySQL与JDBC驱动下载与安装
  16. 机器学习常见算法个人总结
  17. mysql中like,limit,union及union all查询
  18. python连接hive--Pyhive
  19. 独角兽公司超级创始人早期的30个特质
  20. 一文详解bundle adjustment

热门文章

  1. Dropping water balloons
  2. Java——全局变量与局部变量的区别
  3. Visual Studio启动、附加进程调试,多个Web Application时启动多个WebServer关闭方法
  4. 锂离子电池容量保持率和容量恢复率
  5. OSError: [WinError 126] module could not be found(OSError: [WinError 126] 找不到指定的模块)
  6. DPDK-VPP 学习笔记-03 Load Balancer plugin
  7. MyBatis官方文档——动态SQL部分
  8. 熊猫烧香病毒专杀下载
  9. 24套JAVA企业实战项目教程资源分享
  10. 信息学奥赛GoC编程测试题题库