当前位置: 首页 > 面试题库 >

如何将类装饰器与泡菜一起使用?

董畅
2023-03-14
问题内容

我想使用类装饰器(而不是函数装饰器!),例如

def class_decorator(cls):
    class new_cls(cls):
        def run(self, *args, **kwargs):
            print 'In decorator'
            super(new_cls,self).run(*args, **kwargs)
    return new_cls

@class_decorator
class cls(object):
    '''
    a class
    '''
    def run(self):
        print 'called'

并能够腌制对象:

import pickle

a = cls()
a.run()
s = pickle.dumps(a)

但是,泡菜返回错误:

PicklingError: Can't pickle <class '__main__.new_cls'>: it's not found as __main__.new_cls

任何帮助将不胜感激!


问题答案:

腌制一个类时,将 __腌制该类

名称
,而不是其值
。如果class_decorator返回一个 名称 未在模块顶层定义的新类,则会出现错误:

PicklingError: Can't pickle <class '__main__.new_cls'>: it's not found as __main__.new_cls

您可以通过将新修饰的类命名为未修饰的类来避免该错误:

new_cls.__name__ = cls.__name__

然后代码运行无误:

import pickle

def class_decorator(cls):
    class new_cls(cls):
        def run(self, *args, **kwargs):
            print 'In decorator'
            super(new_cls,self).run(*args, **kwargs)
    new_cls.__name__ = cls.__name__
    return new_cls

@class_decorator
class cls(object):
    def run(self):
        print 'called'

a = cls()
print(a)
# <__main__.cls object at 0x7f57d3743650>

a.run()
# In decorator
# called

s = pickle.dumps(a)
# Note "cls" in the `repr(s)` below refers to the name of the class. This is
# what `pickle.loads` is using to unpickle the string
print(repr(s))
# 'ccopy_reg\n_reconstructor\np0\n(c__main__\ncls\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n.'

b = pickle.loads(s)
print(b)
# <__main__.cls object at 0x7f57d3743690>

b.run()
# In decorator
# called


 类似资料:
  • 问题内容: 考虑这个小例子: 哪个打印 为什么参数(应该是Test obj实例)没有作为第一个参数传递给装饰函数? 如果我手动进行操作,例如: 它按预期工作。但是,如果我必须事先知道某个函数是否装饰,它就破坏了装饰器的全部目的。这里的模式是什么,还是我误会了什么? 问题答案: tl; dr 您可以通过将类作为描述符并返回部分应用的函数来解决此问题,该函数从中应用对象作为参数之一,如下所示 实际问题

  • 我想从Log4j 1.x迁移到Log4j 2.x。所以我尝试使用Log4j-1.2-api。jar,如本文所述。我的应用程序实现了org.apache.log4j.spi。LoggingEvent,但我找不到将LoggingEvent与log4j 2.x api桥一起使用的方法。我是否可以将LoggingEvent与log4j 2.2一起使用? 谢谢。

  • 问题内容: 在Python中的lambda函数上使用装饰器有什么语法?例: 结果如下: 但是,当我尝试使用lambda进行相同操作时: 我得到这个: 我觉得这可能是通过允许将语句“插入” lambda使其更通用的好方法。但是,如果存在这样的功能,我不知道语法是什么。 问题答案:

  • 在MobX 中使用 ES.next 装饰器是可选的。本章节将解释如何(避免)使用它们。 使用装饰器的优势: 样板文件最小化,声明式代码。 易于使用和阅读。大多数 MobX 用户都在使用。 使用装饰器的劣势: ES.next 2阶段特性。 需要设置和编译,目前只有 Babel/Typescript 编译器支持。 启用装饰器 如果想使用装饰器,请按照以下步骤操作。 TypeScript 启用 tsco

  • 问题内容: 我一直在尝试创建一个可以与python中的函数和方法一起使用的装饰器。它本身并不难,但是在创建带有参数的装饰器时,似乎确实如此。 上面的代码正确地包装了函数/方法,但是对于方法,参数是它正在操作的实例,而不是第一个非自变量。 有没有办法判断装饰器是应用于函数而不是方法,并进行相应处理? 问题答案: 扩大方法。可以将其概括为装饰器装饰器。 这样,您可以使装饰器自动适应其使用条件。 请注意

  • 问题内容: 这是课程: 现在,我试图从类中“反射”此方法: 问题答案: 只有一个。 另一种选择是。 其他原语也是如此。

  • 我已经定制了我的执行器/信息endpoint,并且我想使用来自头的信息授权对另一个服务的调用。 我在这里实现了InfoContributor:https://www.baeldung.com/spring-boot-info-acture-custom 我想接受方法中的请求头。对于任何用户定义的RESTendpoint,我都可以定义参数并访问头。 但不幸的是,的方法只采用一个参数。 如何访问方法中

  • 问题内容: 如何在Python中制作两个装饰器,以完成以下工作? …应返回: 我并不是想HTML在实际的应用程序中采用这种方式-只是想了解装饰器和装饰器链接的工作方式。 问题答案: 查看文档,以了解装饰器如何工作。这是您要求的: