Python 使用 @ 符号装饰一个对象。

huangapple go评论86阅读模式
英文:

python decorating an object with @

问题

以下是您的代码的翻译部分:

class Sandwich():
    height = 5
    width = 8

    def ingredients(self):
        print("我有面包")
    
class Cheese_decorator():
    def __init__(self, obj):
        self.obj = obj
        # 在这里还有其他内容,使得传递的对象除了下面要装饰的方法之外,变得与原对象相同

    # 被装饰的方法
    def ingredients(self):
        self.obj.ingredients()
        print("我还有奶酪")
     
    # 在这里可以添加其他要装饰的方法

sandwich = Sandwich() # 这个三明治不会被装饰
cheese_sandwich = Cheese_decorator(Sandwich()) # 这个三明治被装饰了

sandwich.ingredients() # 输出我有面包
cheese_sandwich.ingredients() # 输出我有面包我还有奶酪

至于您提到的使用@语法的方式来创建装饰对象的问题,Python的@语法通常用于装饰器,而不是用于创建装饰对象。如果您想要将装饰对象赋给变量,可以按照您之前的方式创建Cheese_decorator的实例。

英文:

I want to achieve the decorator design pattern in python using the @ syntax, my code:

class Sandwich():
    height = 5
    width = 8

    def ingredients(self):
        print("I have bread")
    
class Cheese_decorator():
    def __init__(self,obj):
        self.obj = obj
        #something else here so the object becomes the same as the passed one except for the methods to decorate below

    #decorated method
    def ingredients(self):
        self.obj.ingredients()
        print("I also have cheese")
     
    #any other method to decorate here

sandwich = Sandwich() # this sandwich wont be decorated
cheese_sandwich = Cheese_decorator(Sandwich()) # this sandwich is decorated

sandwich.ingredients() # prints I have bread
cheese_sandwich.ingredients() # prints I have bread I also have cheese

is there anything I can do like:

sandwich = Sandwich()
cheese_sandwich = @Cheese_decorator
                  sandwich

?
I want to have the decorated object as a var

答案1

得分: 2

无论你读到什么理论性的文本关于“装饰器模式”——这不是 Python 中装饰器的本质。

@ 语法用于转换函数或类,通常结果本身可调用。如果对类进行装饰,结果将是修改过的类(或新类),它将创建实例,而不是像你的例子中那样直接创建实例。

此外,由于它可应用于 defclass 块,装饰对象的结果名称是语句中给出的名称(def 后面或 class 关键字后面的名称)。它还意味着 @ 语法与一个语句组合,并且因此不是一个“表达式”,因此无效于赋值右侧或其他任意位置:@decorator 语法要求它自成一行。

也就是说,你的代码示例,使用 cheese_sandwich = Cheese_decorator(Sandwich()) 正如它所示,符合书上所述的“装饰器模式”,你可以这样称呼它。只是它在 Python 中不符合“装饰器语法”。

英文:

Regardless of whatever theoretical text you got to read "decorator pattern" - that is not what decorators are in Python.

The @ syntax is meant to transform either a function or a class - and usually, the result is callable itself. If a class is decorated, the result is the class modified (or a new class), that will create instances, not instances themselves, like in your example.

Moreover, as it is applicable either on a def or on a class block, the resulting name for the decorated object is the name given in the statement. (Either the name after def or after the class keyword). It also implies the @ syntax composes with one statement, and therefore is not an "expression" - and therefore invalid on the right side of an assignment, or other arbitrary places: the @decorator syntax requires it to be in a line by itself.

That said, your code example, using the the cheese_sandwich = Cheese_decorator(Sandwich()) as it is, conforms with the "decorator pattern" from text books, and you may call it so. It just won't work with the "decorator syntax" from Python.

huangapple
  • 本文由 发表于 2023年6月1日 07:56:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377928.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定