知识点大纲
python 闭包:
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
#闭包函数的实例
# outer是外部函数 a和b都是外函数的临时变量
def
outer(
a ):
b =
10
# inner是内函数
def
inner():
#在内函数中 用到了外函数的临时变量
print(a+b)
# 外函数的返回值是内函数的引用
return inner
if
__name__ ==
'__main__':
# 在这里我们调用外函数传入参数5
#此时外函数两个临时变量 a是5 b是10 ,并创建了内函数,然后把内函数的引用返回存给了demo
# 外函数结束的时候发现内部函数将会用到自己的临时变量,这两个临时变量就不会释放,会绑定给这个内部函数
demo = outer(
5)
# 我们调用内部函数,看一看内部函数是不是能使用外部函数的临时变量
# demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数
demo()
# 15
demo2 = outer(
7)
demo2()
#17
闭包中内函数修改外函数局部变量:
#修改闭包变量的实例
# outer是外部函数 a和b都是外函数的临时变量
def
outer(
a ):
b =
10
# a和b都是闭包变量
c = [a]
#这里对应修改闭包变量的方法2
# inner是内函数
def
inner():
#内函数中想修改闭包变量
# 方法1 nonlocal关键字声明
nonlocal b
b+=
1
# 方法二,把闭包变量修改成可变数据类型 比如列表
c[
0] +=
1
print(c[
0])
print(b)
# 外函数的返回值是内函数的引用
return inner
if
__name__ ==
'__main__':
demo = outer(
5)
demo()
# 6 11
一点需要注意:使用闭包的过程中,一旦外函数被调用一次返回了内函数的引用,虽然每次调用内函数,是开启一个函数执行过后消亡,但是闭包变量实际上只有一份,每次开启内函数都在使用同一份闭包变量
#coding:utf8
def
outer(
x):
def
inner(
y):
nonlocal x
x+=y
return x
return inner
a = outer(
10)
print(a(
1))
#11
print(a(
3))
#14
闭包有啥用啊?
3.1装饰器!装饰器是做什么的??其中一个应用就是,我们工作中写了一个登录功能,我们想统计这个功能执行花了多长时间,我们可以用装饰器装饰这个登录模块,装饰器帮我们完成登录函数执行之前和之后取时间。
3.2面向对象!经历了上面的分析,我们发现外函数的临时变量送给了内函数。大家回想一下类对象的情况,对象有好多类似的属性和方法,所以我们创建类,用类创建出来的对象都具有相同的属性方法。闭包也是实现面向对象的方法之一。在python当中虽然我们不这样用,在其他编程语言入比如avaScript中,经常用闭包来实现面向对象编程
3.3实现单利模式! 其实这也是装饰器的应用。单利模式毕竟比较高大,,需要有一定项目经验才能理解单利模式到底是干啥用的,我们就不探讨了。
装饰器:记录程序运行时间实例
import time
def
run_time(
func):
def
bower(*
args):
start = time.time()
func(*args)
end = time.time()
print(
'
%s
run
%s
s' % (func.
__name__, (end-start)))
return bower
@run_time
def
fun1(
name,
n):
for i
in
range(n):
print(
"
%d
hello,
%s
!" % (i,
str))
@run_time
def
wite(
n):
time.sleep(n)
import time
class
MyClass(
object):
threading_lock = threading.Lock()
def
__init__(
self):
time.sleep(
1)
def
__new__(
cls, *
args, **
kw):
if
not
hasattr(MyClass,
'_instance'):
MyClass._instance =
object.
__new__(
cls)
return MyClass._instance
a = MyClass()
b = MyClass()
print(
id(a),
id(b))
# 4508922600 4508922600
斐波那契数列:
def
fib
(
n
):
a
=
0
b
=
1
while
b
<
n:
print
(b)
a, b
=
b, a
+
b
fib(
5
)
python2与python3的主要差异:
没啥差异,就是2020年2.7就不维护了,So~选3吧!
生成器版:
def
fib
():
prev, curr
=
0
,
1
while
True
:
yield
curr
prev, curr
=
curr, curr
+
prev
>>>
f
=
fib()
>>>
list
(islice(f,
0
,
10
))
[
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
]
lambda函数
s =
lambda
x:
"yes"
if x==
1
else
"no"
print(s(
3-
2))
# yes
add =
lambda
x,
y : x+y
print(add(
1,
2))
# 结果为3
Python深浅拷贝:
1,不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。
2,可变类型:
=浅拷贝: 值相等,地址相等
copy浅拷贝:值相等,地址不相等
deepcopy深拷贝:值相等,地址不相等
Python垃圾回收机制:
python采用的是引用计数
机制为主,
标记-清除
和
分代收集
两种机制为辅的策略
GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使用。GC彻底把程序员从资源管理的重担中解放出来,让他们有更多的时间放在业务逻辑上。但这并不意味着码农就可以不去了解GC,毕竟多了解GC知识还是有利于我们写出更健壮的代码。
Python迭代对象、迭代器、生成器:
# 普通代码
def
something
():
result
=
[]
for
...
in
...:
result.append(x)
return
result
# 生成器重构后
def
iter_something
():
for
...
in
...:
yield
x
Python类中super()和__init__()的关系:
钻石继承
class
Base():
def
__init__(
self):
print (
'Base create')
class
childA(
Base):
def
__init__(
self):
Base.
__init__(
self)
print (
'creat A ')
class
childB(
Base):
def
__init__(
self):
# super(childB, self).__init__()
Base.
__init__(
self)
print (
'creat B ')
class
T(
childA,
childB):
def
__init__(
self):
childA.
__init__(
self)
childB.
__init__(
self)
print (
'creat T ')
t = T()
'''
Base create
creat A
Base create
creat B
creat T
'''
super解决
class
Base():
def
__init__(
self):
print (
'Base create')
class
childA(
Base):
def
__init__(
self):
super(childA,
self).
__init__()
print (
'creat A ')
class
childB(
Base):
def
__init__(
self):
super(childB,
self).
__init__()
print (
'creat B ')
class
T(
childA,
childB):
def
__init__(
self):
super(T,
self).
__init__()
print (
'creat T ')
t = T()
'''
Base create
creat B
creat A
creat T
'''