目标使用一个全局变量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
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
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()
在不改变目标函数的同时增加额外的功能
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
某些场景下才需要使用单例设计模式,不是所有情况下都是用单例模式
总结:
示例代码:
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")
了解什么是进程、线程?
了解什么是并行执行?
现代操作系统如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统
进程就是一个程序,运行在系统之上,那么便称这个程序为一个运行进程,并分配进程ID方便系统管理
线程就是归属于进程的,一个进程可以开启多个线程,执行不同的的工作,是进程的实际工作单位
类比:
进程好比一家公司,是操作系统对程序进行运行管理的单位
线程好比是公司的员工,进程可以有多个线程(员工),是进程实际的工作者
操作系统中可以运行多个进程,即多任务运行
一个进程内可以运行多个线程,即多线程运行
进程之间是内存隔离的,即不同的进程拥有各自的内存空间。这就类似于不同的公司拥有不同的办公场所
线程之间是内存共享的,线程是属于进程的,一个进程的多个线程之间是共享这个进程所拥有的内存空间的。这就好比公司员工之间是共享公司的办公场所
并行执行的意思指的是同一时间做不同的工作
进程之间就是并行执行的,操作系统可以同时运行好多程序,这些程序都是在并行执行
除了进程之外,线程其实也是可以并行执行的,比如一个python程序,完全可以做到:
一个线程在输出:你好
一个线程在输出:hello
像这样一个程序在同一时间做两件乃至多件不同的事情,我们称之为:多线程并行执行
目标:掌握使用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()
输出:
我在唱歌,啦啦啦...
我在跳舞,嘟嘟嘟...
我在唱歌,啦啦啦...我在跳舞,嘟嘟嘟...
我在跳舞,嘟嘟嘟...我在唱歌,啦啦啦...
我在唱歌,啦啦啦...我在跳舞,嘟嘟嘟...
我在跳舞,嘟嘟嘟...我在唱歌,啦啦啦...
我在跳舞,嘟嘟嘟...我在唱歌,啦啦啦...
等等...
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()
输出:
我在唱歌,啦啦啦
我在跳舞,呱呱呱
我在跳舞,呱呱呱我在唱歌,啦啦啦
我在跳舞,呱呱呱我在唱歌,啦啦啦
我在唱歌,啦啦啦我在跳舞,呱呱呱
我在唱歌,啦啦啦我在跳舞,呱呱呱
等等...
1.threading 模块的使用:
# 创建线程对象
tread_obj = threading.Thread(target = func)
# 启动线程执行
thread_obj.start()
2.如何调参
args和kwargs