python学习点滴记录

时间:2021-08-19 22:00:42
  • 名称空间与作用域
  • 闭包函数
  • 装饰器
  • 迭代器
  • 生成器
  • 三元表达式、列表解析、生成器表达式

名称空间与作用域

函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数

def bar():
print('from bar')

def foo():
print('from foo')
bar()

foo()

函数的嵌套定义:在一个函数的内部,又定义了另外一个函数

def f1():
x
=1
def f2()
print('from f2')
f2()
f1()

在函数内部定义的变量或者函数只能在内部调用,除非通过return的方式返回在外面调用

 

名称空间:专门用来存放名字与变量值绑定关系的地方
  内置名称空间:python自带的名称空间,在python解释器启动时产生
  全局名称空间:在执行文件时产生,存放文件级别定义的名字;不是内置的,也不是函数中定义的名字,就是全局的
  局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间,用来存放该函数定义的名字,在函数调用时生效,结束后释放。
  加载顺序:内置》全局》局部             查找顺序:局部》全局》内置 从里到外 

x=0
def f1():
x
=1
def f2():
x
=2
def f3():
x
=3
print(x)
f3()
f2()
print('f1========',x)
f1()

作用域:作用的范围

  全局作用域:可以理解为内置和全局名称空间

  局部作用域:可以理解为局部名称空间,临时存活,局部有效

locals()可以查看局部作用域

globals()可以查看全局作用域

python学习点滴记录

global 局部位置设置全局变量;nonlocal 局部设置外层变量

LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间

优先掌握:作用域关系,在函数定义时就已经固定,与调用位置无关,除非是调用前已经被修改

  闭包函数

  定义在函数内部的函数,包含对外部作用域名字的引用,而不是对全局作用域名字的引用,那么该内部函数就成为闭包函数

  闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

  闭包函数的应用:

    惰性计算

python学习点滴记录

 装饰器

开放封闭原则:对拓展是开放的,对修改是封闭的

装饰器本身可以是任意调用对象

装饰器遵循的原则:

  1、不修改被装饰对象的源代码;2、不修改被调用对象的调用方式

目的:

  在遵循原则的前提下为其他函数添加新功能

@装饰器名,必须写在需要被装饰的函数de正上方

装饰器的固定形式

def login(func):
def wrapper(*args,**kwargs):
res
=func(*args,**kwargs)
return res
return wrapper

执行login函数,将下方的函数传入auth函数并将结果赋值给函数 

python学习点滴记录python学习点滴记录
import time
def timmer(func):
def warrper(*args,**kwargs):
start_time
=time.time()
res
=func(*args,**kwargs)
end_time
=time.time()
print(end_time-start_time)
return res
return warrper
@timmer
def get():
url
='http://www.baidu.com'
def MyGet():
time.sleep(
1)
return requests.get(url).text
return MyGet()
@timmer
def my_print(name):
time.sleep(
0.5)
print('print %s'%name)
get()
my_print(
'Tianle')
View Code

编写简单身份验证的装饰器

python学习点滴记录python学习点滴记录
import time

current_user
={'user':None}
def login(func):
def warrper(*args,**kwargs):
i
=0
while i<3:
if current_user['user']:
res
= func(*args, **kwargs)
return res
user
=input('plz input your name:')
password
=input('plz input your password:')
with open(
'db.txt',encoding='utf-8') as f:
user_dic
=eval(f.read())
if user in user_dic and password==user_dic[user]:
print('认证通过')
res
=func(*args,**kwargs)
return res
else:
print('用户密码密码错误,请重试')
i
+=1
if i==3:
print('失败次数过多')
break
return warrper
@login
def my_print(name):
time.sleep(
0.5)
print('print %s'%name)
my_print(
'Tianle')
@login
def my_print1(name):
time.sleep(
0.5)
print('print %s'%name)
my_print1(
'Lele')
View Code

有参装饰器:简单的理解就是闭包函数外面再包一层,包三层就够了

python学习点滴记录python学习点滴记录
import time
current_user
={'user':None}
def auth(auth_type='file'):
def login(func):
def warrper(*args,**kwargs):
if auth_type=='file':
i
=0
while i<3:
if current_user['user']:
res
= func(*args, **kwargs)
return res
user
=input('plz input your name:')
password
=input('plz input your password:')
with open(
'db.txt',encoding='utf-8') as f:
user_dic
=eval(f.read())
if user in user_dic and password==user_dic[user]:
print('认证通过')
res
=func(*args,**kwargs)
return res
else:
print('用户密码密码错误,请重试')
i
+=1
if i==3:
print('失败次数过多')
break
elif auth_type=='mysql':
print('mysql')
else:
print('auth_type error')
return warrper
return login
@auth()
def my_print(name):
time.sleep(
0.5)
print('print %s'%name)
my_print(
'Tianle')
@auth
def my_print1(name):
time.sleep(
0.5)
print('print %s'%name)
my_print1(
'Lele')
View Code

装饰器补充: 

1、wraps #在使用装饰器时保留被装饰函数的文档;也就是将被装饰的函数文档传给装饰器

python学习点滴记录python学习点滴记录
import requests
from functools import wraps #导入模块
import time
def timmer(func):
@wraps(func)
#引用
def warrper(*args,**kwargs):
start_time
=time.time()
res
=func(*args,**kwargs)
end_time
=time.time()
print(end_time-start_time)
return res
return warrper
@timmer
def get():
'''爬虫'''
url
='http://www.baidu.com'
def MyGet():
time.sleep(
1)
return requests.get(url).text
return MyGet()
print(get.__doc__)
View Code

2、一个函数添加多个装饰器:先运行的装饰器先生效

python学习点滴记录python学习点滴记录
import requests
import time
def timmer(func):
def warrper(*args,**kwargs):
start_time
=time.time()
res
=func(*args,**kwargs)
end_time
=time.time()
print(end_time-start_time)
return res
return warrper
def login(func):
def warrper(*args,**kwargs):
i
=0
while i<3:
user
=input('plz input your name:')
password
=input('plz input your password:')
if user=='Tianle' and password=='123':
print('认证通过')
res
=func(*args,**kwargs)
return res
else:
print('用户密码密码错误,请重试')
i
+=1
if i==3:
print('失败次数过多')
break
return warrper

@timmer
@login
def get():
'''爬虫'''
url
='http://www.baidu.com'
def MyGet():
time.sleep(
1)
return requests.get(url).text
return MyGet()
get()
View Code

 


 迭代器

重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值

凡是对象有__iter__方法:对象.__iter__, 该对象就是可迭代对象

什么是迭代器对象:
1:有__iter__,执行得到仍然是迭代本身
2:有__next__


#迭代器对象的优点
1:提供了一种统一的(不依赖于索引的)迭代方式
2:迭代器本身,比起其他数据类型更省内存

python学习点滴记录python学习点滴记录
# s='hello'
#
l=['a','b','c','d']
#
t=('a','b','c','d')
#
dic={'name':'egon','sex':'m',"age":18}
#
set1={1,2,3}
#
f=open('db.txt')

# s.__iter__()
#
l.__iter__()
#
t.__iter__()
#
dic.__iter__()
#
set1.__iter__()
#
f.__iter__()
View Code
python学习点滴记录python学习点滴记录
l=[1,3,4,5,6,7]
d
={'name':'Tianle','age':18}
l_iter
=l.__iter__()
# print(l_iter.__next__())
#
print(l_iter.__next__())
#
print(l_iter.__next__())
#
d_iter=d.__iter__()
# print(d_iter.__next__())
#
print(d_iter.__next__())

while True:
try:
i
=next(l_iter)
print(i)
except StopIteration:
break

while True:
try:
k
=next(d_iter)
print(k,d[k])
except StopIteration:
break
View Code

#迭代器对象的缺点

1:一次性,只能往后走,不能回退,不如索引取值灵活
2:无法预知什么时候取值结束,即无法预知长度

python学习点滴记录python学习点滴记录
l=['a','b','c','d']
for item in l: #iter_l=l.__iter__()
print(item)


for item in {1,2,3,4}:
print(item)


with open(
'a.txt') as f:
# for line in f: #i=f.__iter__()
# print(line)
print(f is f.__iter__())
View Code

生成器

在函数内部包含yield关键字,那么该函数执行的结果就是生成器

生成器其实就是迭代器

yield和return的比较

功能:1、把函数的结果做成迭代器 2、函数暂停与再继续运行的状态是由yield

相同:都有返回值

不同:return只能返回一次值,而yield可以返回多次值

 

三元表达式:

x=1
y
=2
if x > y:
print(x)
else:
print(y)
print(x) if x > y else print(y)

print('True') if True and False else print('False')

列表解析

l=[]
for i in range(10):
l.append(i)
print(l)

#只允许一个判断条件的情况下使用列表解析
print([i for i in range(10) if i >5] )

nums
=[1,2,3,4,5,6]
print([i**2 for i in nums if i >3])

names
=['a_sb','b_sb','c','d_sb']
print([i for i in names if i.endswith('sb')])

生成器表达式

g=('egg%s' %i for i in range(1000))
print(g)
print(next(g))
print(next(g))
print(next(g))

with open(
'a.txt',encoding='utf-8') as f:
# res=max((len(line) for line in f))
res=max(len(line) for line in f)
print(res)

print(max([1,2,3,4,5,6]))

with open(
'a.txt',encoding='utf-8') as f:
g
=(len(line) for line in f)
print(max(g))
print(max(g))
print(max(g))