一些进阶功能的使用 3个月前

1. 闭包

不定义全局变量, 让函数持续访问或修改一个外部的变量

nonlocal是一个关键字, 用于在嵌套函数中声明一个变量为非局部变量 默认情况下, 内部函数只能读取外部函数的变量, 而不能修改它们 在内部函数中使用nonlocal关键字声明一个变量时 Python会沿着作用域链向上查找, 找到最近的外部函数中具有相同名的变量, 并将其标记为非局部变量 nonlocal关键字只能在嵌套函数中使用,而不能在全局作用域或单独的函数中使用 无需通过定义全局变量,就可以通过函数实现持续访问,操作某个值 闭包使用的变量在函数内,很难被错误的误改

def account_mount(total = 0):
    def atm(money, choose = True):
        nonlocal total
        if choose:
            total += money
            print(f"put money: +{money}, remain:{total}")
        else:
            total -= money
            print(f"get money: -{money}, remain:{total}")
    return atm

atm = account_mount()
atm(100)
atm(100)
atm(100, False)
#put money: +100, remain:100
#put money: +100, remain:200
#get money: -100, remain:100

缺点 : 由于一直持续的引用外部函数的变量,会占用内存

2. 装饰器

不修改原函数内容情况下为函数添加新功能

import time

def outer(sleep):
    def inner():
        print("now sleep")
        sleep()
        print("now get up")
    return inner

@outer #装饰器 等价于 sleep = outer(sleep)
def sleep():
    print("sleeping")
    time.sleep(2)

sleep()
#now sleep
#sleeping
#now get up

#若没有装饰器则需要这样写
sheep = outer(sleep)
sheep()

3. 多线程

import threading,time

def sing(song):
    while True:
        print(f"sing {song}")
        time.sleep(1)


def dance(music):
    while True:
        print(f"dance {music}")
        time.sleep(1)

sing = threading.Thread(target = sing, args = ("kk", )) #返回的是Thread对象 , arg要以元组的形式传出
dance = threading.Thread(target = dance, kwargs = {"music" : "msg"})  #kwargs要以字典的形式传出

sing.start()
dance.start()

target: 指定线程要执行的函数或可调用对象 默认是 None args: 指定传递给 target 的位置参数。默认是 () 元组 kwargs: 指定传递给 target 的关键字参数 默认是 {} 字典 daemon: 指定线程是否是守护线程, 守护线程在主线程结束后会自动终止, 默认是 None, 表示继承主线程的守护状态 name: 指定线程的名字, 默认会生成一个唯一的线程名, 如 Thread-1、Thread-2

4. 网络编程

#server端

import socket
#创建一个socket对象
socket_severe = socket.socket()
      
#服务端绑定在本机和端口
socket_severe.bind(("localhost", 8888))
      
#设置服务端允许连接的数量
socket_severe.listen(1)

#等待客户端连接,阻塞语句, 成功链接了才会执行下一句, 返回一个二元元组
client_socket, client_address = socket_severe.accept()
print(f"client address is {client_address}")

while True:
    client_msg = client_socket.recv(1024).decode("UTF-8")
    #阻塞语句,只有成功链接了才会执行下一句
    print(f"client send : {client_msg}")
      
    severe_sentmsg = input("reply to client : ")
    client_socket.send(severe_sentmsg.encode("UTF-8"))
    if severe_sentmsg == 'exit':
        break
    
client_socket.close()
socket_severe.close()
#client端

import socket
#创建一个socket对象
client_socket=socket.socket()
#客户端连接具体的服务端
client_socket.connect(("localhost",8888))

while True:
    sent_data=input("send server is : ")
    if sent_data == "exit":
        break
    client_socket.send(sent_data.encode("UTF-8"))
    recv_data = client_socket.recv(1024)
    print(f"server reply : {recv_data.decode('UTF-8')}")
client_socket.close()

5. 正则表达式

正则表达式, 又称规则表达式( Regular Expression), 是使用单个字符串来描述、匹配某个句法规则的字符串 常被用来检索、替换那些符合其个模式(规则)的文本

import re # RE模块

str = "python ppypyyp python"
result = re.match("python",str) #match对象实例化, 0索引到len-1索引如果不是 所查找的, 忽略掉后面直接返回none 
print(result) #<re.Match object; span=(0, 6), match='python'>
print(result.span()) #(0, 6)
print(result.group()) #python

str = "ppppythonnn pp pythonnn"
result = re.search("python",str) #只找第一个, 失败返回none
print(result) #<re.Match object; span=(3, 9), match='python'>
print(result.span()) #(3, 9)
print(result.group()) #python

result = re.findall("python",str)
print(result) #['python', 'python']

元字符匹配

字符 描述
. 匹配除换行符之外的任何单个字符
[] 匹配[]中列举的字符
\d 匹配任何数字(等同于[0-9]
\D 匹配任何非数字
\w 匹配任何字母数字或下划线字符
\W 匹配任何非字母数字或下划线字符
\s 匹配任何空白字符(空格、制表、换行)
\S 匹配任何非空白字符

数量匹配

字符 描述
* 匹配0次或多次
+ 匹配1次或多次
? 匹配0次或1次
{n} 精确匹配n
{n,} 匹配至少n
{n,m} 匹配至少n次,但不超过m

边界匹配

字符 描述
^ 匹配字符串的开始
$ 匹配字符串的结束
\b 匹配单词边界
\B 匹配非单词边界
\A 匹配整个字符串的开始
\Z 匹配整个字符串的结束

分组匹配

字符 描述
() 用于创建分组
| 匹配左右任意一个表达式

案例

只能数字和字母, 长度6-10
^[0-9a-zA-Z]{6, 10}$

纯数字, 长度5-11, 第一位不为0
^[1-9][0-9]{4, 10}$

只允许qq,163,gmail三种邮箱地址
^[\w]+(\.[\w-]+)*@(qq|163|gmail)(\.[\w-]+)+$
image
EchoEcho官方
无论前方如何,请不要后悔与我相遇。
1377
发布数
439
关注者
2223741
累计阅读

热门教程文档

Redis
14小节
MyBatis
19小节
Golang
23小节
C#
57小节
C++
73小节