昨天回顾
生成器
生成器函数
生成器表达式
面向对象编程
class 语句
class Dog: def __init__(self, *args, **kwargs): 创建一些所有对象共有的属性 self.foods = [] self.total_sleep_time = 0 # .... def eat(self, food): pass def sleep(self, hour): pass
继承
class SuperDog(Dog): def train(self, hour): 导盲犬的驯练 pass def eat(self, food): print( xxxx )
模块内的 __name__ 属性
如果 一个模块是主模块,则 __name__ 绑定 __main__
如果 一个模块不是主模块,则 __name__ 绑定文件名
super() 函数
作用
显示的调用被覆盖的父类方法
示例
class A:
def say_hello(self):
print( Hello A )
class B(A):
def say_hello(self):
print("hello B")
# self.say_hello() 无限递归调用
# 能否在此方法内调用 A类里面的 say_hello()
# 方法1
# A.say_hello(self)
# 方法2 ,super() 会把self 看成是A类的对象
super().say_hello()
b = B()
b.say_hello() # hello B Hello A正则表达式是表明 文字的排列规则的一个字符串, 使用来匹配文字的匹配模式.
作用
用于文字的定位,搜索和内容的提取
| 类别 | 元字符 |
|---|---|
| 匹配字符 | .(不包含) [...] [^...] d D w W s S |
| 匹配重复 | * + ? {n} {m,n} |
| 匹配位置 | ^ $ B |
| 其他 | ` |
示例
# 标识符 的正则表达式
[A-Za-z_][A-Za-z_0-9]*
a* -> a aaaaa
a+ -> a aaaaaa
[ab]+ --> a b abaaabbb
[ab]{3} --> aaa bbb aba
[ab]{3,5}--> aaa aaaaa aabb
# 匹配 .mp3 文件
w.mp3/pre>---> abc.mp3
(w.mp3$)|(w.MP3$) abc.mp3 abc.MP3
w.[mM][pP]3 abc.mP3 abc.mp3 abc.MP3re 模块
import re
方法
re.findall( 正则表达式 , 要匹配的字符串 )
返回成功匹配的字符串的列表
示例
>>> import re
>>> s = ABC123abcd456 13888888899
>>> re.findall( d{3} , s)
[ 123 , 456 , 138 , 888 , 888 ]
>>> re.findall( 1[357][0-9]{9} , s)
[ 13888888899 ]普通字符
ab # 普通字符 只匹配 ab
>>> import re # 导入正则表表达式模块 >>> s = abcdeabca >>> re.findall( ab , s) [ ab , ab ]
或关系
| 匹配两侧任意的正则表达式
>>> import re # 导入正则表表达式模块 >>> s = abcdeabca >>> re.findall( ab|de , s) [ ab , de , ab ]
匹配单个字符串
. 匹配除换行符 以外的任意的一个字符
>>> import re >>> re.findall( 张.丰 , 张三丰,张四丰,张老师 ) [ 张三丰 , 张四丰 ]
匹配字符集
[字符集] 匹配其中的一个字符
>>> import re >>> s = How are you! >>> re.findall( [aeiou] , s) [ o , a , e , o , u ] >>> re.findall( [0-9A-Za-z] , A$%^^%b!#$@!#$0 ) [ A , b , 0 ]
^ 匹配目标字符的开始位置
$ 匹配目标字符的结束位置
>>> re.findall( ^hello , hello world ) [ hello ] >>> re.findall( ^hello , a hello world ) [] >>> re.findall( world/pre>, hello world ) [ world ]
* 匹配前面的字符出现 0 或多次
+ 匹配前面的字符出现 1 或多次
? 匹配前面的字符出现 0 或1次
>>> re.findall( wo* , wooooooo~~w! woo ) [ wooooooo , woo ] >>> re.findall( [A-Z][a-z]+ , Hello World abcd ) [ Hello , World ] >>> re.findall( -?[0-9]+ , name: Jame, age: 18, money:-100 ) [ 18 , -100 ]
{n} # 前面的字符出现n 次
{m,n} # 前面的字符出现m到n次
>>> re.findall( [0-9]{3} , 888 9999 1000000 )
[ 888 , 999 , 100 , 000 ]
>>> re.findall( [0-9]{4,10} , 888 9999 1000000 )
[ 9999 , 1000000 ]d 匹配任意的数字 [0-9]
D 匹配任意的非数字
>>> re.findall( d{1,5} , MySql: 3306, http:80 )
[ 3306 , 80 ]w 匹配普通字符
W 匹配非普通字符
普通字符是指 数字,字母,下划线,汉字
>>> re.findall( w+ , MySql: 3306, http:80 ) [ MySql , 3306 , http , 80 ]
s 匹配空字符
S 匹配非空字符
空字符是指 v f
>>> re.findall( w+s+w+ , hello world ) [ hello world ]
表明单词的边界
B 表明非单词的边界
>>> re.findall(r is , This is a test ) [ is ]
>>> s = SERVER = 192.168.9.102
PORT = 80
SERVERNAME = GAME1
REMOTE = 188.3.69.888
>>> server_re = r SERVERs*=s*[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
server_ip = re.findall(server_re, s)
>>> server_re = r SERVERs*=s*[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
>>> server_ip = re.findall(server_re, s)
>>> server_ip[ SERVER = 192.168.9.102 ]
>>> ip_list = re.findall(r [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3} , server_ip[0]) print("SERVER=", ip_list[0])python 有许多的第三方软件包, 提供了 标准库中没有的功能.
python 的官方支持的软件包的网站: https://pypi.org
安装方法
在Redhat 或 cent OS 上 yum 用于安装 rpm 包
Python 使用 pip3 命令(Windows 上用pip命令) 来安装 Python 的包
打开一个终端
pip3 install 包名
示例
pip3 install wget # 或者 pip3 install pymysql
解决错误的方法
更新 pip3
pip3 install --upgrade pip # 或者 python3 -m pip install -U pip
更换国内的pip 源
# 在用户主目录下创建一个文件夹 .pip mkdir ~/.pip # 在 ~/.pip/文件夹下创建一个文件 pip.conf vim ~/.pip/pip.conf # 写入如下内容 [global] index-url=http://mirrors.aliyun.com/pypi/simple/ [install] trusted-host=mirrors.aliyun.com
也可以百度搜寻其他的源
在使用 pip3 命令时手动指定源
pip3 install -i 源的地址 模块名
示例
pip3 install -i http://mirrors.aliyun.com/pypi/simple/ wget pip3 install -i http://mirrors.aliyun.com/pypi/simple/ pymysql
方式一 : 安装 .whl 的包
# 先下载 XlsxWriter-1.3.8-py2.py3-none-any.whl
pip3 install XlsxWriter-1.3.8-py2.py3-none-any.whl
pip3 install pymysql........whl
方式二: 安装压缩包类型的python 包
# 先下载 XlsxWriter-1.3.8.tar.gz 压缩文件格式的包
tar -xzvf XlsxWriter-1.3.8.tar.gz
cd XlsxWriter-1.3.8 # 进入解压缩后的文件夹
python3 setup.py install # 用 python3 运行setup.py 来安装
安装 mysql-server 或 mariadb-server
# 安装 mariadb yum install mariadb-server # 启动 mariadb 服务 systemctl start mariadb # systemctl restart mariadb systemctl enable maridb # 修改管理员账号的密码为 tedu.cn mysqladmin password tedu.cn # 用 mysql 客户端来登录数据库 mysql -uroot -ptedu.cn
MariaDB [(none)]> CREATE DATABASE nsd21xx DEFAULT CHARSET utf8; Query OK, 1 row affected (0.000 sec) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | nsd21xx | | performance_schema | +--------------------+ 4 rows in set (0.000 sec)
安装 pymysql 包
pip3 install pymysql
下午上课前做的准备工作:
成功安装mysql 数据库或者mariadb 数据库(二选一)
安装pymysql python 的第三方包
用 pymysql 创建数据表
见: pymysql_create_table.py
源代码
file: pymysql_create_table.py
# 导入 pymysql 包 import pymysql # 连接数据库 conn = pymysql.connect( host= localhost , user= root , password= tedu.cn , db= nsd21xx , # 指定操作哪一个数据库 charset= utf8 # 指定操作的字符集 ) # 操作数据库 # 需要使用 游标来操作数据库 cursor = conn.cursor() # 创建游标 # 制定要操作的 SQL 语句 create_dep = CREATE TABLE departments( id INT, dep_name VARCHAR (20), PRIMARY KEY(id) ) # 使用游标 来执行 SQL 语句 cursor.execute(create_dep) # 写入 SQL 语句 conn.commit() # 提交SQL 语句到 服务器去执行 # 如果不再执行SQL 语句则 需要关闭游标 cursor.close() # 操作完数据库,断开连接 conn.close() # > quit;
结果
[root@localhost ~]# mysql -uroot -ptedu.cn Welcome to the MariaDB monitor. Commands end with ; or g. Your MariaDB connection id is 17 Server version: 10.3.27-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type help; or h for help. Type c to clear the current input statement. MariaDB [(none)]> use nsd21xx; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [nsd21xx]> show tables; Empty set (0.000 sec) MariaDB [nsd21xx]> show tables; +-------------------+ | Tables_in_nsd21xx | +-------------------+ | departments | +-------------------+ 1 row in set (0.000 sec) MariaDB [nsd21xx]> desc departments; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | dep_name | varchar(20) | YES | | NULL | | +----------+-------------+------+-----+---------+-------+ 2 rows in set (0.001 sec)
用pymysql 模块实现对 mysql数据库的增删改查
此示例示意 数据库的增删改查操
file: pymysql_create_table.py
# 导入 pymysql 包 import pymysql # 连接数据库 conn = pymysql.connect( host= localhost , user= root , password= tedu.cn , # 密码以实际情况为主 db= nsd21xx , # 指定操作哪一个数据库 charset= utf8 # 指定操作的字符集 ) # 操作数据库 # 需要使用 游标来操作数据库 cursor = conn.cursor() # 创建游标 # 在此处写SQL语句 进行增删改查操作 # 1. 插入数据 insert_sql = INSERT INTO departments VALUES (%s, %s) # # 1.1 插入一条数据到表 departments cursor.execute(insert_sql, (1, 人事部 )) # # 1.2 插入多行数据, 用 executemany 方法 第二个参数是 列表 cursor.executemany(insert_sql, [ (2, 运维部 ), (3, 开发部 ), (4, 测试部 ), (5, 财务部 ), ]) conn.commit() # 把SQL 语句提交到服务器
# 导入 pymysql 包 import pymysql conn = pymysql.connect( host= localhost , user= root , password= tedu.cn , # 密码 db= nsd21xx , # 指定操作哪一个数据库 charset= utf8 # 指定操作的字符集 ) # 操作数据库 # 需要使用 游标来操作数据库 cursor = conn.cursor() # 创建游标 select_sql = SELECT id, dep_name FROM departments cursor.execute(select_sql) # 2.1 取出一行数据 result1 = cursor.fetchone() print(result1) # 2.2 取出2行数据 result2 = cursor.fetchmany(2) print(result2) # 2.3 取出剩余的全部数据 result3 = cursor.fetchall() print(result3)
# 导入 pymysql 包 import pymysql conn = pymysql.connect( host= localhost , user= root , password= tedu.cn , # 密码 db= nsd21xx , # 指定操作哪一个数据库 charset= utf8 # 指定操作的字符集 ) # 操作数据库 # 需要使用 游标来操作数据库 cursor = conn.cursor() # 创建游标 update_sql = UPDATE departments SET dep_name=%s WHERE dep_name=%s cursor.execute(update_sql, ( 人力资源部 , 人事部 )) conn.commit() # 提交
# 导入 pymysql 包 import pymysql conn = pymysql.connect( host= localhost , user= root , password= tedu.cn , # 密码 db= nsd21xx , # 指定操作哪一个数据库 charset= utf8 # 指定操作的字符集 ) # 操作数据库 # 需要使用 游标来操作数据库 cursor = conn.cursor() # 创建游标 delete_sql = DELETE FROM departments WHERE id=%s r = cursor.execute(delete_sql, (5,)) conn.commit()
如果不再执行SQL 语句则 需要关闭游标(末尾添加)
cursor.close()
操作完数据库,断开连接(末尾添加)
conn.close() # > quit;
用此模块可以执行系统命令
文档: https://docs.python.org/zh-cn/3/library/subprocess.html
示例
# 导入模块
import subprocess
# shell=True, 指明此命令在 shell 环境下执行
# stdout=subprocess.PIPE 指明标准输出保存到 stdout 属性中
result = subprocess.run( ls ~ , shell=True, stdout=subprocess.PIPE)
print( 刚才您输入的命令是: , result.args) # 执行的命令 ls ~
print( 此程序运行的返回值是: , result.returncode) # 即 $?
# result.stdout绑定的是 ls ~ 打印在屏幕上的数据的字节串
print( 此程序的标准输出是: , result.stdout.decode())
# 执行一个命令,此命令会产生错误
r = subprocess.run( ls ~/abcdefg , # ~/abcdefg 文件不存在
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
print("ls ~/abcdefg 命令执行的返回值是:", r.returncode) # 2
print("ls ~/abcdefg 命令执行的标准输出是:", r.stdout) # b
print("ls ~/abcdefg 命令执行的标准错误输出是:", r.stderr.decode()) # ls: 无法访问 /root/abcdefg : 没有那个文件或目录示例2
写一个程序,测试此网络内, 192.168.1.1 ~ 192.168.1.254 之间的机器,哪些开机,哪些关机 import subprocess r = subprocess.run( ping -c2 192.168.1.1 &> /dev/null , shell=True) if r.returncode == 0: print( 192.168.1.1 通 ) else: print( 192.168.1.1 不通 )
答案
# 写一个程序,测试此网络内,
# 192.168.1.1 ~ 192.168.1.254 之间的机器,
# 哪些开机,哪些关机
import subprocess
# r = subprocess.run( ping -c2 192.168.1.1 &> /dev/null , shell=True)
# if r.returncode == 0:
# print( 192.168.1.1 通 )
# else:
# print( 192.168.1.1 不通 )
def ping(host_ip):
r = subprocess.run( ping -c2 %s &> /dev/null % host_ip, shell=True)
if r.returncode == 0:
print(host_ip, : up )
else:
print(host_ip, : down )
if __name__ == __main__ :
# 生成 192.168.1.1 ~ 192.168.1.254 范围内的IP
for x in range(1, 255):
ipv4 = 192.168.1.%d % x
# print("IP:", ipv4)
ping(ipv4)一个进程可以有多个执行路径,一般可以每个执行路径分配在不同的CPU 上并行执行, 这种运行方式是多线程
文档:https://docs.python.org/zh-cn/3/library/threading.html
问题
如何能让下面的两个函数同时执行
import time
def say_hello():
for x in range(10):
print("hello!!!")
time.sleep(1)
def say_world():
for y in range(10):
print( world!!! )
time.sleep(1)
say_hello()
say_world()使用多线程
创建线程对象的方法
import threading
# 用threading 的 Thread 类来创建一个线程对象
threading.Thread(target=None, args=(), kwargs={}, *, daemon=None)
示例
import threading
import time
def say_hello():
for x in range(10):
print("hello!!!")
time.sleep(1)
# 用threading 的 Thread 类来创建一个线程对象 用 t 变量绑定
t = threading.Thread(target=say_hello)
# 启动线程
# 用 Thread对象的start() 方法来启动线程,让 线程中 target 绑定的函数,异步执行
t.start()完整示例
import threading # 导入多线程模块
import time
def say_hello():
for x in range(10):
print("hello!!!")
time.sleep(1)
def say_world():
for y in range(10):
print( world!!! )
time.sleep(1)
if __name__ == __main__ :
# 用多线程来并行
# 1. 创建一个线程,绑定 say_hello 函数
t1 = threading.Thread(target=say_hello)
t1.start() # 启动 t1 线程
t2 = threading.Thread(target=say_world)
t2.start()
print("主线程运行结束")
# 串行
# say_hello()
# say_world()此模块实现了 ssh 客户端的功能
ssh 命令 可以远程登录一台主机并远程操作这台主机
安装 paramiko
pip3 install paramiko
示例
# 导入 paramiko 模块
import paramiko
# 创建一个paramko 客户端对象
ssh_clint = paramiko.SSHClient()
# 设置自动接受服务器的主机密钥
ssh_clint.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 登陆远程主机
ssh_clint.connect( 192.168.1.64 , # 远程主机的IP
username= root , # 远程主机的用户名
password= root , # 远程主机的密码
port=22 # ssh 的端口号
)
# 在此处操作远程主机
result = ssh_clint.exec_command( id root; id zhangsan ) # 在远程主机上执行命令
# print( len(result)= , len(result)) # result 绑定三个文件流对象的元组
stdout = result[1] # 得到标准输出
stderr = result[2] # 得到标准错误输出
print("标准输出:", stdout.read().decode())
print("标准错误输出:", stderr.read().decode())
ssh_clint.exec_command( mkdir 魏老师的专用文件夹 )
# 关闭连接
ssh_clint.close() # 相当于在ssh 的内部执行 exit 命令