正则表达式
-我们都使用过Windows/Dos下用于文件查找的通配符(wildcard),也就是*和?,这样可以缩小一些范围来找到自己想要的文件,但是显然这样的搜索的精确度还是不够的,所以引入正则表达式,用更精确的范围更快的匹配到想要的文件。在Python中导入re模块,就可以使用正则表达式了,下面是一些正则表达式的运用
import re
def is_valid_username(username):
"""
判断用户名是否有效(用户名有字母数字下划线构成且长度为6-20个字符)
:param username:
:return:
"""
if 6 <= len(username) <= 20:
for ch in username:
if not ('0' <= ch <= '9' or 'A' <= ch <= 'z'or
'a' <= ch <= 'z'or ch == '_' ):
return False
return True
return False
def main():
username = 'sfhfsdf'
m = re.match(r'^\w{6,20}$', username) # match 是从头开始匹配
m = re.search(r'\w{6,20}',username) # search 是从字符串的任意位置开始匹配
print(m)
print(m.span())
print(m.group())
def foo():
username = input('请输入用户名')
qq = input('请输入QQ号')
pattern1 = re.match(r'^[0-9a-zA-Z]\w{6,20}$', username)
m1 = pattern1
if not m1:
print('请输入有效的用户名')
m2 = re.match(r'^[1-9]\d{4,11}$', qq)
if not m2:
print('请输入有效的QQ号')
if m1 and m2:
print('输入信息有效')
if __name__ == '__main__':
main()
foo()
import re
def main():
sentence = '某某某我操你大爷的日你二爷干你三舅老爷Fuck你姑父'
pure = re.sub('[操艹草肏日干顶]|某某某|fuck|shit', '*', sentence,
flags=re.IGNORECASE) # re.sub 替换匹配字符 flags 标记 忽略大小写
print(pure)
sentence1 = 'you go your way, I will go mine!'
mylist = re.split(r'[\s,!]',sentence1) # split 拆分字符串
print(mylist)
sentence2 = 'aabacddaab'
m = re.match(r'a.*?b', sentence2)
print(m)
def foo(mo):
val = int(mo.group())
return str(val ** 2)
def coo():
sentence3 = 'abc1245dfsgjldkdlkgdfg56eg67hifaifjf'
pattern2 = re.compile(r'\d+')
mylist1 = pattern2.findall(sentence3)
mymap = map(int, mylist1) # 将mylist转换为int类型
print(mymap)
#print(sum(mymap)/len(mymap))
#value = sum1/len(mylist1)
#print()
print(re.sub(r'\d+', foo, sentence3))
print(re.sub(r'P<foo1>\d+', foo, sentence3))
if __name__ == '__main__':
coo()
正则表达式还有很多内容,可以参考网上正则表达式30分钟入门教程。
多线程多进程
比如从网上下载资源,需要等待很长时间,但是我们并是等一个文件下载完了才能下载另一个文件,几个文件是同时下载的,这样是不是就更高效了呢?那么这里就引用了多进程或者多线程。在Python中肯定也是支持多进程多线程的。
import time
from multiprocessing import Process
import os
count = 0
def output(string):
global count
while count < 10:
print(string, end='', flush=True)
count +=1
#time.sleep(0.1)
def main():
p1 = Process(target=output, args=('ping',))
p1.start()
p2 = Process(target=output, args=('pong',))
p2.start()
if __name__ == '__main__':
main()
通过导入multiprocessing模块,建立多进程。在一个进程中我们还可以开子进程。
import subprocess # 子进程
def main():
subprocess.call('notepad')
subprocess.call('calc')
if __name__ == '__main__':
main()
也许从结果上看,多进程和多线程似乎是一样的,其实完全不一样,最大的区别就是多进程是在不同内存上运行的,数据是独立的,而线程是在一个进程下运行的,数据也是共享的。
from time import sleep
from threading import Thread
count = 0
def output(string):
global count
inner_count = 0
while count < 100:
print(string, end='', flush=True)
count += 1
inner_count += 1
print('\n%s打印了%d次' % (string, inner_count))
# sleep(0.01)
class PrintThread(Thread):
def __init__(self, string, count):
super().__init__()
self._string = string
self._count = count
def run(self):
for _ in range(self._count):
print(self._string, end='', flush=True)
def main():
# 守护线程 - 不值得保留的线程,其他线程都执行完了那么守护线程自动结束了
#t1 = Thread(target=output, args=('ping',),daemon=True)
#t1.start()
#t2 = Thread(target=output, args=('pong',),daemon=True)
#t2.start()
p1 = PrintThread('ping', 100).start()
p1 = PrintThread('pong', 100).start()
if __name__ == '__main__':
main()
创建多线程,我们可以通过创建类去继承Thread,重写run方法,也可以直接通过Thread创建对象通过target= 传入函数或方法,args=传入参数,注意需传入元组。最后都直接调用start方法开启线程。
程序设计多进程和多线程都是非常常见的,那么什么时候用多进程,什么时候用多线程呢?
import time
import random
from threading import Thread
from multiprocessing import Process
# 如果多个任务之间没有任何的关联(独立自任务)而且希望利用CPU的多核特性
# 那么我们推荐使用多进程
def download(filename):
print('开始下载%s...' % filename)
delay = random.randint(5, 15)
time.sleep(delay)
print('%s下载完成,用时%d秒' % (filename, delay))
class DownloadTask(Thread):
def __init__(self, filename):
super().__init__()
self._filename = filename
# 钩子函数(hook) / 回调函数(callback)
def run(self):
download(self._filename)
def main():
start = time.time()
# t1 = Thread(target=download, args=('Python从入门到住院.pdf',), daemon=True)
# t2 = Thread(target=download, args=('Pekin Hot.avi',), daemon=True)
# t1.start()
# t2.start()
# t1.join()
# t2.join()
# p1 = Process(target=download, args=('Python从入门到住院.pdf',))
# p2 = Process(target=download, args=('Pekin Hot.avi',))
# p2.start()
# p1.join() # 等待进程结束
# p2.join()
t3 = DownloadTask(('Python从入门到住院.pdf',))
t4 = DownloadTask(('Pekin Hot.avi',))
t3.start()
t4.start()
t3.join()
t4.join()
# download('Python从入门到住院.pdf')
# download('Pekin Hot.avi')
end = time.time()
print('总共耗费了%f秒' % (end - start))
if __name__ == '__main__':
main()
刚才有提到,多线程是数据共享的,那么多个线程同时去访问和修改变量时,必定会遭成数据混乱的情况,那么这是我们通过lock只允许一个线程去访问和修改,只有这个线程完了之后另一个线程才能去访问和修改,保证数据的正常。相信你肯定也想到了,这样做势必会增加程序的执行时间,所以我们应尽量去避免使用lock
import time
from threading import Thread, Lock
class Account(object):
def __init__(self):
self._balance = 0
self._lock = Lock()
@property
def balance(self):
return self._balance
def deposit(self, money):
# 当多个线程同时访问一个资源的时候 就有可能因为竞争资源导致资源的状态错误
# 被多个线程访问的资源我们通常称之为临界资源 对临界资源的访问需要加上保护
if money > 0:
self._lock.acquire() # 获得锁
try:
new_balance = self._balance + money
time.sleep(0.01)
self._balance = new_balance
finally:
self._lock.release() # 开锁,下一个进程才能访问
class AddMoneuThread(Thread):
def __init__(self, account):
super().__init__()
self._account = account
def run(self):
self._account.deposit(1)
def main():
account = Account()
tlist = []
for _ in range(100):
t = AddMoneuThread(account)
tlist.append(t)
t.start()
for t in tlist:
t.join()
print('账户余额%d元' % account.balance)
if __name__ == '__main__':
main()
网络编程
网络是一门极其复杂的课程,内容繁多,可以通过计算机网络基础来初步了解一下网络的构成及运作,这样才能理解网络编程的代码。下面是一个服务器的代码。
from socket import socket # 导入套接字
import datetime
def main():
# 创建一个基于TCP协议的套接字对象
# 因为我们做的是应用级的产品或服务所以可以利用现有的传输服务来实现数据传输
server = socket()
# 绑定ip地址(网络上主机的身份标识)和端口用来区分不同服务的IP地址的扩展)
server.bind(('10.7.189.87', 6789)) # 开端口
# 开始监听客户端的连接
server.listen(512) # 队列长度
print('服务器已经启动正在监听...')
while True:
# 通过accept方法接受客户端的连接
# accept方法是一个阻塞式的方法 如果没有客户连上来
# 那么accept方法就会让代码阻塞 直到有客户端连接成功才返回
# accept方法返回一个元组 元组中的第一个值是代表客户端的对象
# 元组中的第二个值又是一个元组 其中有客户端的IP地址和客户端的端口
client, addr = server.accept()
print(addr, '连接成功')
curr_time = datetime.datetime.now()
client.send(curr_time.__str__().encode('utf-8'))
client.close()
if __name__ == '__main__':
main()
这是一个客户端与服务器对应
from socket import socket
def main():
client = socket()
client.connect(('10.7.189.79', 6789))
data = client.recv(1024)
print(type(data))
print(data.decode('utf-8'))
if __name__ == '__main__':
main()
下面是一个发邮件的代码:
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from smtplib import SMTP
def main():
sender = SMTP('smtp.163.com')
sender.login('jw531969539@163.com','qwerasdfjw123')
message = MIMEMultipart()
message['Subject'] = '请查收附件中数据'
text_msg = MIMEText('附件中有本月关键数据请查收!', 'plain', 'utf-8')
message.attach(text_msg)
att2 = MIMEText(open('ss.xlsx', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/vnd.ms-excel'
att2["Content-Disposition"] = 'attachment; filename="ss.xlsx"'
message.attach(att2)
# content = """
#你在干嘛呀,一起来玩吧!
# """ # 普通文本
# message = MIMEText(content, 'plain', 'utf-8')
#message['Subject'] = '地点'
sender.sendmail('jsdf5319@163.com', ['45344265@qq.com'],
message.as_string())
if __name__ == '__main__':
main()