黑马程序员Python(续)

文章目录

    • 52综合案例(暂时不学)
    • -----------------------------------------------------------------------------以下是Python高级技巧编程----------------------------------------------
    • 53 闭包
      • 53.1 一个简单的闭包例子:
      • 53.2 总结:
    • 54 装饰器
      • 54.1 案例介绍
      • 54.2 装饰器的作用:
      • 54.3 总结:
    • 55 设计模式
      • 55.1 单例模式
      • 55.2 工厂模式
    • 56 多线程
      • 56.1 进程
      • 56.2 线程
      • 56.3 多任务运行
      • 56.4 多线程运行
      • 56.5 进程与线程的注意点:
      • 56.6 并行执行
      • 56.7 以上内容总结
      • 56.8 多线程编程
      • 56.9 在创建多个线程时args和kwargs的传参方式
      • 59.10 多线程编程总结
    • 57 网络编程
    • 58 正则表达式
    • 59 递归

52综合案例(暂时不学)

-----------------------------------------------------------------------------以下是Python高级技巧编程----------------------------------------------

53 闭包

目标使用一个全局变量account_amount来记录余额:

account_amount = 0

def atm(num,deposit = True):
    global account_amount
    if deposit:
        account_amount += num
        print(f"存款:+{num},账户余额:{account_amount}")
    else:
        account_amount -= num
        print(f"存款:-{num},账户余额:{account_amount}")
atm(300)
atm(300)
atm(100,False)

以上代码存在问题:
代码在命名空间上(变量定义)不够干净、整洁
全局变量有被修改的风险
将代码改为以下:

def account_create(initial_amount=0):
    def atm(num,deposit = True):
        if deposit:
            initial_amount += num
            print(f"存款:+{num},当前余额:{initial_amount}")
        else:
            initial_amount -= num
            print(f"存款:+{num},当前余额:{initial_amount}")
    return atm

atm = account_create()
atm(10)
atm(10)
atm(10)
atm(10)
atm(6, deposit=False)

这样会报错:


Traceback (most recent call last):
  File "D:/0000***/***/测试.py", line 382, in <module>
    atm(10)
  File "D:/0000***/***/测试.py", line 374, in atm
    initial_amount += num
UnboundLocalError: local variable 'initial_amount' referenced before assignment

得添加nonlocal initial_amount,即:

def account_create(initial_amount=0):
    def atm(num,deposit = True):
        # nonlocal initial_amount
        if deposit:
            initial_amount += num
            print(f"存款:+{num},当前余额:{initial_amount}")
        else:
            initial_amount -= num
            print(f"存款:+{num},当前余额:{initial_amount}")
    return atm

atm = account_create()
atm(10)
atm(72)
atm(26,deposit=False)
atm(4)
atm(6, deposit=False)

输出:

存款:+10,当前余额:10
存款:+72,当前余额:82
存款:+26,当前余额:56
存款:+4,当前余额:60
存款:+6,当前余额:54

53.1 一个简单的闭包例子:

def outer(logo):
    def inner(msg):
        print(f"<{logo}><{msg}><{logo}>")
    return inner
func1 = outer("黑马程序员")
func1("大家好")
func2 = outer("传智教育")
func2("大家好")

输出:

<黑马程序员><大家好><黑马程序员>
<传智教育><大家好><传智教育>

解释:对于inner函数来说变量logo是外部变量,对于outer函数来说变量logo是临时变量
目标:对于函数inner来说,它依赖的外部变量一直都没有变化,又不想这个外部变量不会被改变

一种想法:在inner中是否可以修改变量logo的值呀?
实现方法:使用nonlocal这个关键字去修饰外部函数的变量才能在内部函数中修改它,即修改外部变量
代码:

def outer(num1):
    def inner(num2):
    	nonlocal num1
        num1 += num2
        print(num1)
    return inner
func1 = outer(10)
func1(10)
func1(10)

输出:

20
30

53.2 总结:

黑马程序员Python(续)_第1张图片

54 装饰器

54.1 案例介绍

def sleep():
    import time
    import random
    print("睡觉中....")
    time.sleep(random.randint(1,5))

在不改变sleep函数功能以及函数体的前提下为sleep增加新功能
新功能描述:
在睡眠之前先”打印一下要睡觉了“
在睡眠之后“打印一下要起床了”
内包写法:

def outer(func):
    def inner():
        print("我要睡觉啦")
        func()
        print("我要起床啦")
    return inner
def sleep():
    import time
    import random
    print("睡觉中....")
    time.sleep(random.randint(1,5))

inn = outer(sleep)
inn()

装饰器写法:

def outer(func):
    def inner():
        print("我要睡觉啦")
        func()
        print("我要起床啦")
    return inner

@outer
def sleep():
    import time
    import random
    print("睡觉中....")
    time.sleep(random.randint(1,5))

sleep()

54.2 装饰器的作用:

在不改变目标函数的同时增加额外的功能

54.3 总结:

黑马程序员Python(续)_第2张图片

55 设计模式

55.1 单例模式

黑马程序员Python(续)_第3张图片
黑马程序员Python(续)_第4张图片
黑马程序员Python(续)_第5张图片
创建一个tool.py文件
代码:


class Tools():
    pass

t1 = Tools()
t2 = Tools()

print(id(t1))
print(id(t2))

输出:

D:\Anaconda3\python.exe "D:/0000***/***/tool.py"
2277989643456
2277989508864

进程已结束,退出代码为 0

表示这是两个不同的类对象
再创建一个测试.py文件
代码内容:

from tool import t3

t4 = t3
t5 = t3
print(id(t4))
print(id(t5))

输出:

D:\Anaconda3\python.exe "D:/0000***/***/测试.py"
2747203220432
2747203220432

进程已结束,退出代码为 0

某些场景下才需要使用单例设计模式,不是所有情况下都是用单例模式

总结:

黑马程序员Python(续)_第6张图片

55.2 工厂模式

什么是工厂模式?
黑马程序员Python(续)_第7张图片
以上是基于原生的创造对象的方法
黑马程序员Python(续)_第8张图片
黑马程序员Python(续)_第9张图片

示例代码:

class Person():
    pass

class Worker(Person):
    pass

class Student(Person):
    pass

class Teacher(Person):
    pass

class PersonFactory():
    def get_person(self,p_type):
        if p_type == "w":
            return Worker()
        elif p_type == "s":
            return Student()
        else:
            return Teacher()
            
pf = PersonFactory()
worker = pf.get_person("w")
student = pf.get_person("s")
teacher = pf.get_person("t")

总结:
黑马程序员Python(续)_第10张图片
前两条好处是重点

56 多线程

了解什么是进程、线程?
了解什么是并行执行?
现代操作系统如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统

56.1 进程

进程就是一个程序,运行在系统之上,那么便称这个程序为一个运行进程,并分配进程ID方便系统管理

56.2 线程

线程就是归属于进程的,一个进程可以开启多个线程,执行不同的的工作,是进程的实际工作单位

类比:
进程好比一家公司,是操作系统对程序进行运行管理的单位
线程好比是公司的员工,进程可以有多个线程(员工),是进程实际的工作者

56.3 多任务运行

操作系统中可以运行多个进程,即多任务运行

56.4 多线程运行

一个进程内可以运行多个线程,即多线程运行

56.5 进程与线程的注意点:

进程之间是内存隔离的,即不同的进程拥有各自的内存空间。这就类似于不同的公司拥有不同的办公场所
线程之间是内存共享的,线程是属于进程的,一个进程的多个线程之间是共享这个进程所拥有的内存空间的。这就好比公司员工之间是共享公司的办公场所
黑马程序员Python(续)_第11张图片

56.6 并行执行

并行执行的意思指的是同一时间做不同的工作
进程之间就是并行执行的,操作系统可以同时运行好多程序,这些程序都是在并行执行
除了进程之外,线程其实也是可以并行执行的,比如一个python程序,完全可以做到:
一个线程在输出:你好
一个线程在输出:hello
像这样一个程序在同一时间做两件乃至多件不同的事情,我们称之为:多线程并行执行

56.7 以上内容总结

见以下图片内容黑马程序员Python(续)_第12张图片

56.8 多线程编程

目标:掌握使用threading模块完成多线程编程
绝大多数编程语言,都允许多线程编程
单线程编程代码:

import time
def sing():
    while True:
        print("我在唱歌,啦啦啦...")
        time.sleep(1)
def dance():
    while True:
        print("我在跳舞,嘟嘟嘟...")
        time.sleep(1)
if __name__ == '__main__':
    sing()
    dance()

输出内容:

我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
...

多线程编程:

import time
import threading

def sing():
    while True:
        print("我在唱歌,啦啦啦...")
        time.sleep(1)
def dance():
    while True:
        print("我在跳舞,嘟嘟嘟...")
        time.sleep(1)
if __name__ == '__main__':
    # 创建一个唱歌的线程
    sing_thread = threading.Thread(target=sing)
    # 创建一个跳舞的线程
    dance_thread = threading.Thread(target=dance)

    #启动多个线程  同时执行
    sing_thread.start()
    dance_thread.start()

输出:

我在唱歌,啦啦啦...
我在跳舞,嘟嘟嘟...
我在唱歌,啦啦啦...我在跳舞,嘟嘟嘟...

我在跳舞,嘟嘟嘟...我在唱歌,啦啦啦...

我在唱歌,啦啦啦...我在跳舞,嘟嘟嘟...

我在跳舞,嘟嘟嘟...我在唱歌,啦啦啦...

我在跳舞,嘟嘟嘟...我在唱歌,啦啦啦...
等等...

56.9 在创建多个线程时args和kwargs的传参方式

import time
import threading

def sing(msg):
    while True:
        print(msg)
        time.sleep(1)
def dance(msg):
    while True:
        print(msg)
        time.sleep(1)
if __name__ == '__main__':
    # 创建一个唱歌的线程   给sing函数以args元组的方式传参
    sing_thread = threading.Thread(target=sing,args=("我在唱歌,啦啦啦",))
    # 创建一个跳舞的线程    给dance函数以kwargs字典的方式传参
    dance_thread = threading.Thread(target=dance,kwargs={"msg":"我在跳舞,呱呱呱"})

    #启动多个线程  同时执行
    sing_thread.start()
    dance_thread.start()

输出:

我在唱歌,啦啦啦
我在跳舞,呱呱呱
我在跳舞,呱呱呱我在唱歌,啦啦啦

我在跳舞,呱呱呱我在唱歌,啦啦啦

我在唱歌,啦啦啦我在跳舞,呱呱呱

我在唱歌,啦啦啦我在跳舞,呱呱呱
等等...

59.10 多线程编程总结

1.threading 模块的使用:

# 创建线程对象
tread_obj = threading.Thread(target = func)
# 启动线程执行
thread_obj.start()

2.如何调参
args和kwargs

57 网络编程

58 正则表达式

59 递归

你可能感兴趣的:(python,5G,开发语言)