您的位置:首页 > 编程语言 > Python开发

python之闭包、装饰器、生成器、反射

2020-01-15 10:47 309 查看

1. 函数的作用域

  1.在函数定义时候就固定,与调用位置无关,在调用的时候返回到函数定义的位置

x=1 #全局作用
def f1():      #整个f1函数是定义阶段
def f2():
print(x)
return f2

def foo(func):
x=3
func() #func()调用阶段
x=200  #这样定义x又变成全局了
foo(f1())          #执行foo(f1()) 返回到F1函数里找x所以打印是1不是3

 

生成器

 

 

2.名称空间

内置名称空间:在python解释器启动产生的空间,简单理解就是python自带的方法比如:max()len()

全局名称空间 :在全局定义的好的名称空间,文件级别的产生的 比如:

x=1  #全局作用
def test():
  x=2 #局部作用 print(x) test()

if x=1 y=2 #全局作用
#在执行test()调用的时候先加载内置查找有没有test这个内置函数,如果去全局里查找test这个函数方法,最后局部


 

局部名称空间:在调用函数时候产生局部名称空间 y=2,在调用teset()立马产生了局部作用空间

nonlocal x 函数正上方的x的变量
global x 改成全局的变量

3.闭包函数

闭包函数的作用主要在与装饰器

函数式编程里面闭包只是给函数捆绑死一个值或者状态

1.定义在函数内部的函数

2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用

3.该内部函数就称为闭包函数

 

import requests
#第一种传参闭包
def re(func):
def get():
return requests.get(func).text
return get

baidu=re('http://www.baidu.com')
baidu1=re('http://www.souhu.com')
print(baidu())

#第二种自定义固定值闭包函数
def test():
url='http://www.baidu.com'
def gett():               #gett()是闭合函数外面包裹这个url
return requests.get(url).text
return gett
func=test()
print(func())


def ff():
  url=‘nq.com’
  func() #此时的func已经一种状态就是url这个百度地址不会
ff() #得到的结果是url='http://www.baidu.com'


 

 

4.装饰器

装饰器的定义:1.在不变动主功能函数的前提下,为其添加上新的功能或者状态。

例:比如抓数据时候,我们需要添加计时器,显示抓取用了多少时间,

写一个te函数是计时器功能,这样可以给爬取baidu、搜狐网站添加上这个计时器。

第一种装饰器写法,其实是给闭包函数添加了一个功能

import requests
improt time
#第一种传参闭包,这里当主功能函数
def re(func):
def get():
return requests.get(func).text
return get

baidu=re('http://www.baidu.com')
baidu1=re('http://www.souhu.com')
print(baidu())

#装饰器,给获取百度数据添的用时
def te(func):
def timer():
start=time.time()
func()
stop=time.time()
print("获取数据的时间%s"%(stop-start))
return timer

baidu=te(baidu)
baidu()

 第二种写法

这种方法适合用@装饰器函数名称,上面例子是闭包函数,已经闭包了是不可以种@的来装饰建议使用  函数调用方式

n是表示给传参的函数,以防万一最要用*args,**kwargs的方式

 

1 import psutil
2 def count(func):
3     def timer():
4         fu=psutil.cpu_count()
5         print(fu)
6         func(1)
7     return timer
8
9
10 #查看cpu使用情况的一个函数
11 @count
12 def main(n):
13     res=psutil.cpu_times()
14     print(res)
15     print(n)
16
17 #查看Process的一个函数n
18 @count
19 def test(t):
20     fl=psutil.Process
21     print(fl)
22     print(t)
23
24
25 test()
26 main()
View Code

 

装饰器的细节问题:

from functools import wraps 在装饰器中添加显示备注信息,如下代码
import psutil
from functools import wraps
def count(func):
@wraps(func)    #这里需要添加wraps这个装饰器
def timer():
fu=psutil.cpu_count()
print(fu)
func(1)
return timer

#查看cpu使用情况的一个函数
@count
def main(n):
'''
这个是mian函数的

'''
res=psutil.cpu_times()
print(res)
print(n)
#return 123 如果函数里有return 打印这个函数结果时候显示空 因为,main显示已经被conunt函数装饰了,所以要在timer里面retrun才对 print(main.__doc__) #这里是打印上面的备注信息

 生成器

生成器:不断调用和返回值,生成器

迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器,可以直接作用于for循环的对象统称为可迭代对象

# def Pycharm(name):
#     food_list = []
#     food = yield food_list
#     print("%s想吃%s" % (name, food))
#     food_list.append(food)
#     print(food_list)
#
#
# res = Pycharm('alex')
# next(res)   #next 会停留在 food=yield这里,send传送后继续执行下面的内容
# res.send('fangfood')

 python之反射

反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr  获取成员、检查成员、设置成员、删除成员下面逐一介绍先看例子

它的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动

 

class func():

def __init__(self):
self.teacher='teacher'
self.student='student'
self.age='ee'
self.name='name'

def test01(self):
print('反射机智显示test01功能%s' %self.teacher)

def test02(self):
print('反射机智显示test02功能%s' %self.student)

func=func()

def run():
'''

:return:通过res用户输入相对应的变量、函数方法
通过反射机制来判断、增删添改
'''
res=input('>>我想执行里面的函数:').strip()
hasa=hasattr(func,res)         #hasattr 可以判断func类中是否存在res传入的变量或者函数方法
res=getattr(func,res,'not find') #getattr 可以获取传入方法或者函数的执行结果,
# 得到是内存地址需要通过res()来展示内容
#not find意思 如果没有找到相对应的变量和函数 通过print(res())来打印出notfind

# print(res())
tom=setattr(func,res,18)      #setattr 可以修改传入变量的结果 比如self age=17 通过setattr可以修改成18
print(func.age)
delattr(func,'age')           #delattr 删除age这个变量
print(func.age)

# setattr(func,res,18)
run()

 

转载于:https://www.cnblogs.com/yingfei/p/9762656.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
diaojixiang3725 发布了0 篇原创文章 · 获赞 0 · 访问量 283 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: