python2 nonlocal_python非零返回

python2 nonlocal_python非零返回nonlocal可以将一个变量声明为非本地变量,在python的lru_cache看到了使用defdecorator(func):a=1defwrapper(*args,**kwargs):nonlocalaa+=1returnfunc()returnwrapper实例中,当a变量是不可变类型时,因为包装函数引用了a,装饰器执行结束,在包装函数里改变a的值,需要…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196825.html原文链接:https://javaforall.net

(0)
上一篇 2025年9月19日 下午12:43
下一篇 2025年9月19日 下午1:22


相关推荐

  • Python抛出异常_python抛出异常的作用

    Python抛出异常_python抛出异常的作用在工作中都会遇到异常报错问题,那么在这抽空码一些内容以作记录。在python中不同的异常可以用不同的类型(python中统一了类与类型,类型即类)去标识,不同的类对象标识不同的异常,一个异常标识一种错误AttributeError#试图访问一个对象没有的树形,比如foo.x,但是foo没有属性xIOError#输入/输出异常;基本上是无法打开文件ImportError#无法引入模块或包;基本上是路径问题或名称错误Indentati.

    2022年10月17日
    5
  • PetShop4架构设计分析(三,四)

    PetShop4架构设计分析(三,四) petshop4.0详解之三(PetShop数据访问层之消息处理)三、PetShop数据访问层之消息处理在进行系统设计时,除了对安全、事务等问题给与足够的重视外,性能也是一个不可避免的问题所在,尤其是一个B/S结构的软件系统,必须充分地考虑访问量、数据流量、服务器负荷的问题。解决性能的瓶颈,除了对硬件系统进行升级外,软件设计的合理性尤为重要。在前面我曾提到,分层式结构设计可能会在一定

    2022年10月16日
    4
  • vim编辑器

    vim编辑器

    2022年4月3日
    46
  • 一文搞定7大流行后端框架:Spring、Netty、MyBatis、Hibernate、Dubbo…「建议收藏」

    一文搞定7大流行后端框架:Spring、Netty、MyBatis、Hibernate、Dubbo…「建议收藏」框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。可以说,一个框架是一个可复用的设计构件,它规定了应用的体系结构,阐明了整个设计、协作构件之间的依赖关系、责任分配和控制流程,表现为一组抽象类以及其实例之间协作的方法,它为构件复用提供了上下文(Context)关系。因此构件库的大规模重用也需要框架。今天给大家分享49篇【后端编程框架】相关精选学习资…

    2022年5月1日
    60
  • DHCP协议简述

    DHCP协议简述DHCP(DynamicHostConfigurationProtocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作,主要有两个用途:给内部网络或网络服务供应商自动分配IP地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段,在RFC2131中有详细的描述。DHCP有3个端口,其中UDP67和UDP68为正常的DHCP服务端口,分别作为DHCPServer…

    2022年5月24日
    47
  • 物理地址介绍「建议收藏」

    物理地址介绍在存储器里以字节为单位存储信息,为正确地存放或取得信息,每一个字节单元给以一个唯一的存储器地址,称为物理地址(PhysicalAddress),又叫实际地址或绝对地址。计算(此类计算可直接使用计算机进行计算,总结来说就是进制之间的转换):地址(字节编址)10242^10b1KB100000000001K…

    2022年4月4日
    211

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号