首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python Decorator继承问题

Python Decorator继承问题
EN

Stack Overflow用户
提问于 2021-12-14 22:44:51
回答 2查看 54关注 0票数 0
代码语言:javascript
复制
class Foo():
    help_message = ""

    def Help_Decorator(func):
        def wrapper(data, context, caller):
            try:
                if data[0] == "help":
                    return(help_message) #<--- cannot access this locally
                else:
                    return func(data,context,caller)
            except:
                return func(data,context,caller)
    return wrapper

class Bar(Foo):
    help_message = "A real help message!"
    @foo.Help_Decorator
    def Run(data,context,caller):
        pass

如何在不将help_message作为参数传递到Help_Decorator中的情况下从Help_Decorator中访问Bar的

EN

回答 2

Stack Overflow用户

发布于 2021-12-14 22:51:55

因为Run是一个实例方法,data是一个Bar实例。通常情况下,这将按照约定被称为self,但是给它一个不同的名称并不会改变函数调用的语义。

因此,您应该能够在您的data.help_message函数中访问wrapper。(我还希望data[0]为您提供一个TypeError,除非Bar已经实现了__getitem__。)

如果您的目的是调用类上的Run而不是实例,则不应该将其定义为实例方法。让它成为一个类方法:

代码语言:javascript
复制
class Bar(): 
    help_message = "A real help message!" 

    @classmethod
    @foo.Help_Decorator
    def Run(cls, data, context, caller): 
        pass

现在,在包装器中,您可以:

代码语言:javascript
复制
    def Help_Decorator(func):
        def wrapper(cls, data, context, caller):
            try:
                if data[0] == "help":
                    return(cls.help_message)
                else:
                    return func(cls, data, context, caller)
            except:
                return func(cls, data, context, caller)
    return wrapper

请注意,Help_Decorator不需要成为FooBar的方法。

合在一起:

代码语言:javascript
复制
class Foo():
    help_message = ""

    def Help_Decorator(func):
        def wrapper(cls, data, context, caller):
            try:
                if data[0] == "help":
                    return(cls.help_message)
                else:
                    return func(cls, data, context, caller)
            except:
                return func(cls, data, context, caller)
        return wrapper

class Bar(Foo):
    help_message = "A real help message!"

    @classmethod
    @Foo.Help_Decorator
    def Run(cls, data, context, caller):
        return "derp"

print(Bar.Run(["help"], 1, 0))

指纹:

代码语言:javascript
复制
A real help message!

Foo从代码中删除会产生完全相同的结果;在实现Help_Decorator的位置与其修饰方法的类之间不需要任何类型的继承关系:

代码语言:javascript
复制
def Help_Decorator(func):
    def wrapper(cls, data, context, caller):
        try:
            if data[0] == "help":
                return(cls.help_message)
            else:
                return func(cls, data, context, caller)
        except:
            return func(cls, data, context, caller)
    return wrapper

class Bar:
    help_message = "A real help message!"

    @classmethod
    @Help_Decorator
    def Run(cls, data, context, caller):
        return "derp"

print(Bar.Run(["help"], 1, 0))
票数 2
EN

Stack Overflow用户

发布于 2021-12-14 22:57:26

传递给包装器的第一个参数是Run类的一个实例,您应该添加self作为第一个参数。然后您可以引用self.help_message,它将返回在Run类中定义的help_message。

(编辑)如果您想使用装饰器作为类方法,那么只需将其装饰成这样。你的榜样会成为。

代码语言:javascript
复制
class foo(): 
    help_message = "bad" 
 
    @classmethod     
    def Help_Decorator(cls, func): 
        @classmethod 
        def wrapper(cls, data, context, caller): 
            print(data, context, caller) 
            try: 
                if data[0] == "help": 
                    print('helping', cls) 
                    return(cls.help_message) #<--- cannot access this locally 
                else: 
                    return func(data,context,caller) 
            except: 
                return func(data,context,caller) 
        return wrapper 
 
class Bar(): 
    help_message = "A real help message!" 
 
    @foo.Help_Decorator 
    @classmethod 
    def Run(cls, data,context,caller): 
        pass
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70356434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档