gpt4 book ai didi

python-3.x - 如何使用带参数的python装饰器?

转载 作者:行者123 更新时间:2023-12-03 23:07:03 25 4
gpt4 key购买 nike

我想定义一个装饰器,它将通过作为装饰器参数给出的名称注册类。我可以从 stackoverflow 和其他来源中读取许多示例,这些示例展示了如何派生此类(棘手的)代码,但是当适应我的需要时,我的代码无法产生预期的结果。这是代码:

import functools

READERS = {}

def register(typ):
def decorator_register(kls):
@functools.wraps(kls)
def wrapper_register(*args, **kwargs):
READERS[typ] = kls
return wrapper_register
return decorator_register

@register(".pdb")
class PDBReader:
pass

@register(".gro")
class GromacsReader:
pass

print(READERS)

此代码生成一个空字典,而我希望有两个条目的字典。你知道我的代码有什么问题吗?

最佳答案

获取参数(通过 (...) )和装饰(通过 @ )都会导致函数调用。获取参数或装饰的每个“阶段”映射到一个调用,从而映射到装饰器定义中的一个嵌套函数。 register是一个三阶段装饰器,需要尽可能多的调用来触发其最内部的代码。这些,

  • 第一个是参数( (".pdb") ),
  • 第二个是类定义( @... class )和
  • 第三个是类调用/实例化( PDBReader(...) )
  • 这个阶段被破坏了,因为它没有实例化类。

  • 为了将类本身存储在字典中,将其存储在第二阶段。由于不存储实例,因此删除第三个阶段。
    def register(typ):                # first stage: file extension
    """Create a decorator to register its target for the given `typ`"""
    def decorator_register(kls): # second stage: Reader class
    """Decorator to register its target `kls` for the previously given `typ`"""
    READERS[typ] = kls
    return kls # <<< return class to preserve it
    return decorator_register

    请注意,装饰器的结果会替换其目标。因此,您通常应该返回目标本身或等效对象。由于在这种情况下该类会立即返回,因此无需使用 functools.wraps .
    READERS = {}

    def register(typ): # first stage: file extension
    """Create a decorator to register its target for the given `typ`"""
    def decorator_register(kls): # second stage: Reader class
    """Decorator to register its target `kls` for the previously given `typ`"""
    READERS[typ] = kls
    return kls # <<< return class to preserve it
    return decorator_register

    @register(".pdb")
    class PDBReader:
    pass

    @register(".gro")
    class GromacsReader:
    pass

    print(READERS) # {'.pdb': <class '__main__.PDBReader'>, '.gro': <class '__main__.GromacsReader'>}

    关于python-3.x - 如何使用带参数的python装饰器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61884695/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com