zoukankan      html  css  js  c++  java
  • 11月python学习

    11月学习总结

    单例模式

    • 只能创建一个对象
    # 单例模式
    class A:
        __isinstace = None
    
        def __init__(self):
            print('init')
    
        # __new__方法是为对象在内存中开辟内存空间,__init__是为该空间封装属性
        def __new__(cls, *args, **kwargs):
          print('new')
            if not cls.__isinstace:
                cls.__isinstace = super().__new__(cls)
            return cls.__isinstace
    
    
    if __name__ == '__main__':
        a = A()
        aa = A()
    
        print(id(a))
        print(id(aa))
    

    item系列

    • item的所有方法是以访问字典的方式访问对象的所有属性
    • attr的所有方法是以操作变量的方法操作对象的内部属性
    • 对于访问、更新、创建、删除不存在的属性时会调用attr相关的方法
    class A:
        def __init__(self, v):
            self.v = v
    
        def __getitem__(self, key):
            print('getitem')
    
        def __setitem__(self, key, value):
            print('setitem')
    
        def __getattr__(self, key):
            print('getattr')
    
        def __setattr__(self, key, value):
            print('setattr')
    
        def __delitem__(self, key):
            print('delitem')
    
        def __delattr__(self, key):
            print('delattr')
    
    if __name__ == '__main__':
        a = A(1)
        a['v'] = 1
        a.v = 2
    
        v = a.v
        vv = a['v']
    
        del a.v
        del a['v']
    

    上下文管理

    class A:
        def __init__(self):
            print('init')
    
        def __enter__(self):
            print('enter')
            return 1
    
        def __exit__(self, exception_type, exception_value, traceback):
            print('exit')
    
    
    if __name__ == '__main__':
        # a 为__enter__方法返回的值
        with A() as a:
            print(a)
    

    反射

    首先获取目标的所有方法、属性集,然后再获取。

    attr()方法就是通过参数获取相应对象中的值。

    其中一个很重要的功能就是hasattr()和getattr(),因为python一切皆对象,所以说所有的属性和方法是以字典的形式保存的,即key-->value,键名对应着值。若要获取一个对象的属性的值,就是前往该对象的属性、方法集合中去寻找相应的键,若存在就返回值,否则就报错,若调用getattr就会做相应的错误处理(返回一句提示);若要更新一个对象中的值,则是前往属性、方法集合中去寻找相应的键,并更新值,若键不存在就更新集合,添加一个键,并默认为其赋予默认的值。

    class A:
        def __init__(self, value):
            self.value = value
    
    
    
    if __name__ == '__main__':
        a = A(1)
        if hasattr(a, 'b'):
            getattr(a, 'b')
        else:
            print('not find')
    
        print(getattr(a, 'b', 'not find'))
    
    
    def func1():
        print('func1')
    
    def fun2():
        print('func2')
    
    
    # globals()获取当前文件中所有的方法和属性
    # print(globals()['func1']())
    
    
    import sys
    
    # 获取当前主进程模块
    obj = sys.modules['__main__']
    print(obj.__dict__)
    
    

    多进程

    • 单继承
      • 创建方法
        • 创建Process对象
        • 继承Process对象
          • 重写run方法,相当于是target的值,可以通过实现__init__,通过super().__init__()实现传入参数
    • 多进程
      • 创建
        • 多进程
          • 多次创建对象
        • 进程池
          • 列表存储
          • Pool对象存储
      • 进程间的通信
        • Queue是位于内存中的一个交换的之间的区域,用于存放两个进程之间需要公用的数据。
        • 进程池
          • Manager().Queue()
        • Queue()(使用方法与进程池的Queue类似,传入一个数据表示一次性最多可以缓存的消息数量)
        • 一般的锁
        • 死锁(各持一把对方都需要的锁)

    python中由于GIL(全局解释锁)的存在,一次只能执行一个进程,并不能达到真正意义上的多进程

    # 多进程
    from multiprocessing import Process, Pool,Manager, Lock
    import time
    
    def func1():
        print('fucn1')
    
    def func2():
        print('func2')
    
    
    def func3(i):
        print('接收', i)
        time.sleep(1)
        print('结束', i)
    
    
    def func3(queue, i, lock):
        lock.acquire()
        queue.put(f'放入{i}')
        print(f'成功放入{i}')
        time.sleep(2)
        lock.release()
    
    def func4(queue):
        data = queue.get()
        print('拿出数据:', data)
        time.sleep(0.5)
    
    class MyProcess(Process):
        def __init__(self, args):
            self.args = args
            super().__init__(target=self.run, args=args)
        def run(self):
            print('获取', self.args[0])
            time.sleep(1)
            print('结束', self.args[0])
    
    
    if __name__ == '__main__':
        # p1 = Process(target=func1)
        # p2 = Process(target=func2)
        start = time.time()
    
        # 进程池
        # processes = [Process(target=func3, args=(i, )) for i in range(100)]
    
        # pool = Pool()
        # for i in range(100):
        #     pool.apply_async(func3, (i,))
        #
        # pool.close()
        # pool.join()
    
        # for p in processes:
        #     p.start()
        #
        # for p in processes:
        #     p.join()
        # p1.start()
        # p2.start()
        #
        # p1.join()
        # p2.join()
    
        # 继承实现
        # processes = [MyProcess(args=(i,)) for i in range(100)]
        # for p in processes:
        #     p.start()
        # for p in processes:
        #     p.join()
    
    
        # 进程间通信
        queue = Manager().Queue()
        lock = Lock()
    
    
        processes = [Process(target=func3, args=(queue, i, lock)) for i in range(50)]
    
        processes += [Process(target=func4, args=(queue,)) for _ in range(40)]
    
        for p in processes:
                p.start()
    
        for p in processes:
                p.join()
    
        # 锁
    
    
        end = time.time()
        print('主进程结束, 耗时:', end-start)
    
    

    多线程

    • 进程是计算机分配资源的基本单位,线程是计算机执行的基本单位。
    • 线程必须存在于进程中。
    • 计算密集型任务用进程,I/O密集型用线程。
    • 线程的创建与进程的创建十分类似。
    • 线程的五种状态:
      • 创建
      • 就绪
      • 运行
      • 阻塞/睡眠/挂起
      • 死亡
    # 多线程
    from threading import Thread
    import time
    a = 0
    def fun1():
        print('func1')
    
    def fun2():
        print('func2')
    
    def fun3():
        global a
        print('计算开始:', a)
        for i in range(1000000):
            a += 1
        print('计算结束:', a)
    
    def func4():
        global a
        print('计算开始', a)
        for i in range(100000):
            a -= 1
        print('计算结果', a)
    class MyThread(Thread):
        def run(self):
            print('MyThread')
            time.sleep(1)
    
    if __name__ == '__main__':
    
        start = time.time()
    
        # 单线程
        # t1 = Thread(target=fun1)
        # t2 = Thread(target=fun2)
        #
        # t1.start()
        # t2.start()
        #
        # t1.join()
        # t2.join()
    
        # 多线程
    
        # threads = [MyThread() for _ in range(100)]
        #
        # for t in threads:
        #     t.start()
        # for t in threads:
        #     t.join()
    
        # 多线程通信, 以及多线程之间的并发所造成的数据有误
    
        threads = [Thread(target=fun3) for _ in range(100)]
        # threads += [Thread(target=func4) for _ in range(100)]
    
    
    
    
        for t in threads:
            t.start()
    
        for t in threads:
            t.join()
    
        end = time.time()
    
        print('最终结果:',a)
        print('耗时:', end-start)
    

    信号量semaphore

    表示同一时间内最多几个线程为就绪状态,准备被系统调度运行。

    from threading import Thread, Semaphore
    import time
    
    def func1(i):
        s.acquire()
        print(f'开始执行{i}')
        time.sleep(1)
        print(f'结束行执行{i}')
        s.release()
    
    if __name__ == "__main__":  
    
        start = time.time()  
        s = Semaphore(5)
        threads = [Thread(target=func1, args=(i, )) for i in range(100)]
        for t in threads:
            t.start()
        for i in threads:
            t.join()
    
        end = time.time()
    
        print('执行完成,耗时',end - start)
    
    

    python程序的执行过程

    • 当执行python程序时,操作系统将程序和pythpn解释器加载到内存中,并开辟一块空间用于执行程序
    • python解释器分为编译器和虚拟机,首先编译器将python编译成C程序,然后虚拟机将C程序转换成字节码,然后输出机器码

    同步锁

    按照指定顺序执行程序即为同步,否则就为异步。

    from threading import Thread, Lock
    import time
    
    def func1():
        while True:
            lock1.acquire()
            print('func1')
            time.sleep(0.5)
            lock2.release()
    
    
    def func2():
        while True:
            lock2.acquire()
            print('func2')
            time.sleep(0.5)
            lock3.release()
    
    
    def func3():
        while True:
            lock3.acquire()
            print('func3')
            time.sleep(0.5)
            lock1.release()
    
    
    if __name__ == "__main__":
    
        lock1 = Lock()
        lock2 = Lock()
        lock2.acquire()
        lock3 = Lock()
        lock3.acquire()
    
        t1 = Thread(target=func1)
    
        t2 = Thread(target=func2)
    
        t3 = Thread(target=func3)
    
        t1.start()
        t2.start()
        t3.start()
    
    

    网络编程

    • 一对一
      • tcp 安全,速率较慢
      • udp 快速,每次都是发送的数据包, 易数据丢失
      • tcp & udp
        • 面向连接和不面向连接
        • 占用系统资源
        • 数据流与数据报
        • tcp稳定,保证顺序性, udp可能丢包, 不保证顺序性
        • tcp --> send()/recv(), udp--> sendto(data, addr)/recvfrom()
    • 3次握手
      • 在tcp时,当执行connect()时,就会发生,首先客户端向服务端发送连接请求,服务段返回确认码atk和syn码,表示接收到请求,并告知客户端,客户端收到后返回确认码atk。
    • 4次挥手
      • 在tcp中,当执行close()时,若是客户端,则向服务端发送断开连接请求,服务端收到后响应,返回确认码,然后,服务端再发送消息告知客户端将要断开连接,客户端回应。
    • 全双工聊天室
      • 一对一
      • 一对多

    一般步骤

    1. 导包
    2. 创建套接字
    3. 绑定地址和端口
    4. 监听/发送消息
    5. 关闭套接字

    在OSI7层模型的4层模型中,应用层一下的都是由socket封装。

    一对一

    TCP

    # tcp 服务端
    from socket import *
    
    # tcp
    s = socket(AF_INET, SOCK_STREAM)
    s.bind(('localhost', 9999))
    
    s.listen()
    
    
    new_socket = s.accept() # 返回的是一个套接字和客户端的ip+端口号
    # socket, addr = new_socket
    print(new_socket)
    data = new_socket[0].recv(1024)
    # socket.send(message.encode('utf-8'))
    print(data[1][0])
    
    if len(data) == 0: # 当客户端断开连接时会发送一个长度为0的数据,当检测到长度为0时,说明客户端已经断开连接p
        new_socket[0].close()
    
    s.close()
    
    
    # 客户端
    from socket import *
    
    s = socket(AF_INET, SOCK_STREAM)
    
    s.connect(('localhost', 9999))
    # 客户端请求连接,连接成功后就可以收发消息了
    s.send('hhhhh'.encode('utf-8'))
    s.recv(1024)
    s.close()
    
    

    UDP

    # 服务端
    from socket import *
    
    s = socket(AF_INET, SOCK_DGRAM)
    
    s.bind(('localhost', 9999))
    
    data = s.recvfrom(1024)
    
    print(data)
    
    s.close()
    
    # 客户端
    
    s = socket(AF_INET, SOCK_DGRAM)
    
    s.sendto('hhhh'.encode('utf-8'), ('localhost', 9999))
    
    s.close()
    
    

    全双工聊天室

    一对一

    from socket import *
    from threading import Thread
    import time
    
    # 客户端/服务端(udp) 
    class Send(Thread):
        def run(self):
            while True:
                data = input('>>>')
                s.sendto(data.encode('utf-8'), addr)
                time.sleep(0.5)
    
    class Receive(Thread):
        def run(self):
            while True:
                data = s.recvfrom(1024)
                print(data[0].decode('utf-8'))
                time.sleep(0.5)
     
    
    if __name__ =='__main__':
    
        s = socket(AF_INET, SOCK_DGRAM)
    
        addr = ('localhost', 9999)
        s.bind(('localhost', 8888))
    
        send = Send()
        rece = Receive()
    
        try:
            send.start()
            rece.start()
            send.join()
            rece.join()
        finally:
            s.close()
    

    并发服务器

    线程实现

    from socket import *
    from threading import Thread
    import time
    
    def deal_with_client(socket, addr):
        while True:
            data = socket.recv(1024)
            if len(data) == 0:
                break
            print(data.decode('utf-8'))
            time.sleep(0.5)
        socket.close()
    
    if __name__ == '__main__':
    
        s = socket(AF_INET, SOCK_STREAM)
        s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) # 一般来说一个线程占用一个端口,通过设置这个使得多个线程可以访问同一个端口
        s.bind(('localhost', 8888))
        s.listen()
        while True:
            new_socket, new_addr = s.accept()
            p = Thread(target=deal_with_client, args=(new_socket, new_addr))  
            p.start()  
        s.close()
    
  • 相关阅读:
    socket是什么
    0,1,2 代表标准输入、标准输出、标准错误
    认识程序的执行:从高级语言到二进制,以java为例
    97 条 Linux 运维工程师常用命令总结[转]
    rsync 参数配置说明[转]
    shell 脚本学习之内部变量
    ansible 入门学习(一)
    python 管理多版本之pyenv
    CentOS6 克 隆
    yum 本地仓库搭建
  • 原文地址:https://www.cnblogs.com/JonnyJiang-zh/p/14068134.html
Copyright © 2011-2022 走看看