nonlocal 可以将一个变量声明为非本地变量, 在python的lru_cache看到了使用

def decorator(func):

a = 1

def wrapper(*args, **kwargs):

nonlocal a

a += 1

return func()

return wrapper

实例中, 当a变量是不可变类型时, 因为包装函数引用了a, 装饰器执行结束, 在包装函数里改变a的值, 需要用nonlocal声明a变量. (a是自由变量了)

当a是可变类型时, 可以不用声明nonlocal a

自己再本地试一遍能理解的更加深入

lru_cache源码中的使用, 用来记录hit和miss

只贴出包装函数的部分

f _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):

# Constants shared by all lru cache instances:

sentinel = object() # unique object used to signal cache misses

make_key = _make_key # build a key from the function arguments

PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields

cache = {}

hits = misses = 0

full = False

cache_get = cache.get

cache_len = cache.__len__

lock = RLock()

root = []

root[:] = [root, root, None, None]

if maxsize == 0:

def wrapper(*args, **kwds):

nonlocal misses # 要改变misses,所以用nonlocal声明

misses += 1

result = user_function(*args, **kwds)

return result

elif maxsize is None:

def wrapper(*args, **kwds):

# Simple caching without ordering or size limit

nonlocal hits, misses

key = make_key(args, kwds, typed)

result = cache_get(key, sentinel)

if result is not sentinel:

hits += 1

return result

misses += 1

result = user_function(*args, **kwds)

cache[key] = result

return result

else:

def wrapper(*args, **kwds):

# Size limited caching that tracks accesses by recency

nonlocal root, hits, misses, full

key = make_key(args, kwds, typed)

with lock:

link = cache_get(key)

if link is not None:

# Move the link to the front of the circular queue

link_prev, link_next, _key, result = link

link_prev[NEXT] = link_next

link_next[PREV] = link_prev

last = root[PREV]

last[NEXT] = root[PREV] = link

link[PREV] = last

link[NEXT] = root

hits += 1

return result

misses += 1

result = user_function(*args, **kwds)

with lock:

if key in cache:

# Getting here means that this same key was added to the

# cache while the lock was released. Since the link

# update is already done, we need only return the

# computed result and update the count of misses.

pass

elif full:

# Use the old root to store the new key and result.

oldroot = root

oldroot[KEY] = key

oldroot[RESULT] = result

# Empty the oldest link and make it the new root.

# Keep a reference to the old key and old result to

# prevent their ref counts from going to zero during the

# update. That will prevent potentially arbitrary object

# clean-up code (i.e. __del__) from running while we're

# still adjusting the links.

root = oldroot[NEXT]

oldkey = root[KEY]

oldresult = root[RESULT]

root[KEY] = root[RESULT] = None

# Now update the cache dictionary.

del cache[oldkey]

# Save the potentially reentrant cache[key] assignment

# for last, after the root and links have been put in

# a consistent state.

cache[key] = oldroot

else:

# Put result in a new link at the front of the queue.

last = root[PREV]

link = [last, root, key, result]

last[NEXT] = root[PREV] = cache[key] = link

# Use the cache_len bound method instead of the len() function

# which could potentially be wrapped in an lru_cache itself.

full = (cache_len() >= maxsize)

return result

def cache_info():

"""Report cache statistics"""

with lock:

return _CacheInfo(hits, misses, maxsize, cache_len())

def cache_clear():

"""Clear the cache and cache statistics"""

nonlocal hits, misses, full

with lock:

cache.clear()

root[:] = [root, root, None, None]

hits = misses = 0

full = False

wrapper.cache_info = cache_info

wrapper.cache_clear = cache_clear

return wrapper

python nonlocal 什么意思_python nonlocal的理解使用相关推荐

  1. python nonlocal的用法_python nonlocal 的具体原理

    很多文章都大概列了下nonlocal的具体用法,比如看到几篇文章写的 "nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量" 看完以后我感觉自己是懂了,但光从这句 ...

  2. python列表的加法_Python列表加法理解

    我是Python新手,不能将函数转换为列表理解.理解涉及value函数,其包含类如下:class Card(object): # Lists containing valid candidates f ...

  3. python的整体设计目标_python之总体理解

    作为脚本,python具备了弱类型语言的灵活性,便捷性.这在日常的开发使用中能够大幅度的减轻开发人员的编码负担,开发者也能够将精力集中在程序的逻辑管理和总体构架设计上.一般而言,随着经验的积累,开发人 ...

  4. class在python中的意思_Python中类的理解,Class

    说明Class之前,先写一个Python中Class的代码: 为了便于理解,首先定义三个类:OldMan . YoungMan .Lawyer,其中Lawyer"多继承"前两个类. ...

  5. python 闭包的作用_python中对闭包的理解

    运行环境声明:本人的代码在sublime text 3中写的,可以Ctrl+b运行.python版本是python3.6.如果您直接运行的,请自觉加入if __name__ == '__main__' ...

  6. python中的loop啥意思_Python forloop列表理解

    我是Python的初学者,正在自学列表理解.我几乎把所有的for-loop代码都翻译成了list-comprehension,但是我非常坚持我认为相当简单的循环.在n = 10000 def sim( ...

  7. vscode使用教程python-VSCode下好用的Python插件及配置_python

    这篇文章主要介绍了微软官方的Python插件,已经自带很多功能,下面是插件功能描述,其中部分内容我做了翻译,需要的朋友可以参考下 MS Python插件. 这是微软官方的Python插件,已经自带很多 ...

  8. python中定义数据结构_Python中的数据结构—简介

    python中定义数据结构 You have multiples algorithms, the steps of which require fetching the smallest value ...

  9. python基础知识测试题_Python中的单元测试—基础知识

    python基础知识测试题 Unit testing is the number one skill which separates people who just finished their de ...

最新文章

  1. 1013 - 把握趋势
  2. OpenCV Laplace point/edge detection拉普拉斯点/边缘检测的实例(附完整代码)
  3. java uppercase方法_java-方法引用
  4. 小程序的wx.onAccelerometerChange
  5. java properties读取缓存_java 读取 properties文件的各种方法
  6. Spring AOP之HelloWorld与概念介绍(xml版)
  7. ssh连接虚拟机的linux_openstack系列之运维排障:虚拟机SSH连接失败
  8. Oracle数据库之SQL单行函数---字符函数之TRIM
  9. 2022年最新山西机动车签字授权人模拟试题及答案
  10. mac android使用WiFi安装应用调试程序
  11. [踩坑记录]VS2017+大恒MER-131-210U3C相机
  12. [VBA][EXCEL]插入分页符
  13. 关于python搞笑段子精选_搞笑却有哲理的段子
  14. imx6ull 下 UART5问题
  15. @Transactional的七种事务传播行为
  16. 日历插件(项目总结)(包括mobiscroll.js LCalendar 和Calendar这三个日历插件)
  17. 基于opencv实现透视变换(Python)
  18. c#8583_解析ISO8583报文实例
  19. 后端返回有序map,前端却展示无序map
  20. amazon海淘+CUL中美速递转运详细教程(免税)

热门文章

  1. 中南财经政法大学计算机实践试题及答案,中南财经政法大学2010计算机应用基础期末考试试卷...
  2. VSC/SMC(十三)——快速和非奇异Terminal滑模控制(含程序模型)
  3. 天纵智能软件快速开发列表+统计图分析插件
  4. vtkDataArray vtkFloatArray
  5. [NLP] 自然语言处理基础任务介绍
  6. 线程池使用:CPU密集型和IO密集型
  7. 二进制安全:转化大师漏洞复现:Boxoft Convert Master 1.3.0 - ‘wav‘ SEH Local Exploit
  8. echarts实现气泡图(气泡之间不叠加)
  9. LeetCode_Heap_剑指 Offer 40. 最小的k个数 【堆,泛型实现,自定义比较器】【C++/java】【简单】
  10. 多国雪藏外星人秘密?:人类身上藏着外星人秘密?