python进阶2

IO编程

  文件读写

with open(‘file’,‘r’,encoding=‘gbk’) as f:  #读gbk编码的文件

f.read()

  StringIO和BytesIO : 内存读写;f.getvalue():获得写入后的内存文件内容

  操作文件和目录:操作文件和目录的函数一部分在os模块中,一部分在os.path模块中

import os
print(os.path.abspath('.'))  #查看当前目录的绝对路径

# 在某个目录下创建一个新目录
os.path.join('C:/Users/viruser.v-desktop/PycharmProjects/hexin', 'testdir')
os.mkdir('C:/Users/viruser.v-desktop/PycharmProjects/hexin/testdir.py')
os.rmdir('C:/Users/viruser.v-desktop/PycharmProjects/hexin/testdir')   #删除目录
# 文件操作\
# os.rename('test.py', 'practice.py')

print(os.path.split('hexin/testdir'))  # 只对字符串起分割作用,('hexin', 'testdir')
print(os.path.splitext('testdir.py'))  # 结果:('testdir', '.py')

# 列出该项目下的所有目录
list_dir = [x for x in os.listdir('..')if os.path.isdir('../'+x)]
# 列出该目录下所有py文件
list_file = [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
# 在当前目录及当前目录下的所有子目录下查找文件名包含指定字符串的文件,并打印出相对路径

import os
print(os.path.isfile('../test.py'))
def select_file(path, str):
    # path = os.path.abspath(pwd)
    for x in os.listdir(path):
        dir = os.path.join(path, x)  # 拼接x的绝对路径
        if os.path.isdir(dir):  # os.path.isdir()的参数需为绝对路径,os.path.idfile()同理
            select_file(dir, str)
        else:
            if str in x:
                # print(dir)
                n = os.path.abspath('..')
                m = dir.replace(n,'..')
                print(m)


pwd = os.path.abspath('..')
print(pwd)
str = 'test'
select_file(pwd, str)

   序列化:将变量从内存中变成可存储和传输的过程

dumps将对像序列化为一个str, dump(d,f)将对象序列化后并写入文件

loads反序列化,loadd(f)从文件中反序列化出对象

import pickle
# 将变量序列化后保存至文件中
d = {'a':3}
with open('pickle.txt', 'wb') as f:
   pickle.dump(d, f)

# 将对象从磁盘读到内存中(读出的变量与原来的变量不为同一个对象,只是内容相同)
'''with open('pickle.txt', 'rb') as f:
    b = pickle.load(f)
print(b)
'''

    JSON 格式序列化:序列化为字符串

在不同编程语言之间传递对象,必须把对象序列化为标准格式,json表示为一个字符串,可被所有语言读取,json传输快且可直接在web页面中读取

import json

d = {'a':3}
with open('pickle.txt', 'w') as f:
   json.dump(d, f)   # 等同于:f.write(json.dumps(d))

json_str = '{"age": 20, "score": 88, "name": "Bob"}'
json.loads(json_str)

实例的序列化,将对象转化为可序列对象

class Stucent():
    def __init__(self,name, age):
        self.name = name
        self.age = age

s = Stucent('bob',20)

def studict(std): # 该函数输出一个字典
    return{
        'name':std.name,
        'age':std.age
    }
m = json.dumps(s, default=studict)
print(json.dumps(s, default= lambda obj:obj.__dict__)) #实例有dict属性, default调用函数将任意一个对象转换为可序列对象

def dictstu(d):  # 该函数返回Stucent的实例
    return Stucent(d['name'], d['age'])
print(json.loads(m, object_hook = dictstu)) #反序列化为一个原字典,object_hook调用函数将dict转换为实例

 进程和线程

多进程(可使用进程池实现)

# 启动一个子进程(当前进程为父进程)并等待其结束
from multiprocessing import Process
import os

# 子进程要执行的代码
def run_pro(name):
    print('child processing %s' % os.getpid())  #getpid()获取进程id

if __name__ == '__main__':
    print('parent processing %s' % os.getpid())
    p = Process(target=run_pro, args=('test',)) # 创建子进程,传入执行函数和函数的参数,
    p.start()  #  用start启动进程
    p.join() # 等待子进程结束后再继续往下运行,通常用于进程间的同步
    print('end')

进程间通信

# 进程间通信,创建两个进程,一个往queue中写数据,一个从queue中读数据
from multiprocessing import Process, Queue
import time

# 写数据进程执行代码;
def write(q):
    print('write process')
    for value in ['a', 'b', 'c']:
        print('写入进程写入值%s' %value)

        q.put(value)
        time.sleep(2) 

# 读数据进程执行代码
def read(q):
    print('read process')
    for i in range(3):
        value=q.get()
        print('读进程读取的值%s' % value)

if __name__=='__main__':
    q = Queue()  # 父进程创建queue,并传给每个子进程
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    pw.start() #启动写入进程
    pr.start() #启动读取进程

    pw.join() #等待pw进程结束(pw进程结束后继续往下运行)

  多线程

任何进程默认启动一个线程,该线程可称为主线程,主线程可启动新的线程,current_thread():返回当前线程的实例

# 创建线程
import time, threading

# 新线程执行的代码:
def loop():
    print("new thread:%s is running" % threading.current_thread().name )
    n = 0
    while n<5:
        print("%s, %s"%(threading.current_thread().name, n))
        n = n+1
        time.sleep(1)
    print('new thread:%s is end' % threading.current_thread().name)

print("thread: %s is running" % threading.current_thread().name)
t = threading.Thread(target=loop, name='thread_1')  # 创建线程以及给新线程命名
t.start()  # 启动新线程
# t.join()  # 等待新线程执行结束后再继续往下执行
print("thread:%s is end" % threading.current_thread().name)

 

  :当线程共享一个变量时,由于线程是由操作系统调度的,因此会出现线程交替执行,使得变量被修改错误,因此要使用锁保证一个线程执行时其他线程不能同时执行,只能等待

 

#
# 创建两个线程共享变量, 创建变量balance = 0(银行存款),先存后取

import time, threading
lock = threading.Lock()  # 创建锁
balance = 0
def change_it(n):
    global balance
    #先存后取后,balance结果为0
    balance = balance + n  # 由于修改balance时,存在多条语句,线程可能中断,导致多个线程将同一个对象内容改乱, 因此对balance的修改需要上锁
    balance = balance -n

def run_thread(n):
    for i in range(2000000):
        lock.acquire()  # 获取锁
        try:
            change_it(n)  #修改balance
        finally:
            lock.release() #修改完后,释放锁
t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(9,))
t1.start()
t2.start()
t2.join()
t1.join()
print(balance)

死锁:由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方的锁时,可能会造成死锁,导致多个线程全部挂起。

 

   ThreadLocal : 多线程,线程之间不交互,常用场景:为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等

import threading

# 创建全局ThreadLocal对象:
local_school = threading.local()

def process_student():
    # 获取当前线程关联的student:
    std = local_school.student
    print("%s in %s" % (std, threading.current_thread().name))

def process_thread(name):
    # 绑定threadlocal的student
    local_school.student = name
    process_student()

t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()

 

posted @ 2021-07-15 11:22  小小鱼鱼儿  阅读(58)  评论(0编辑  收藏  举报