【问题标题】:decorating base class methods in python在python中装饰基类方法
【发布时间】:2021-07-18 09:25:37
【问题描述】:

我有一个python类,例如:

from abc import ABC, abstractmethod


class Drawing(ABC):

    @abstractmethod
    def draw(self):
        pass


class Sketch(Drawing):

    # overriding abstract method
    def draw(self):
        print("Drawing a sketch")



# Driver code
R = Sketch()
R.draw()

这是他想要达到的目标:

创建一个实现draw()接口的抽象绘图类。以 Sketch 类的形式开发 Drawing 类的子类。用 Sketchdraw 的消息让 draw() 接口更具体。

问题: 但我也想创建改变素描风格的装饰器(例如“铅笔素描”或“钢笔素描”)。 我的问题是我怎样才能做到正确,我在下面的代码中所做的是否正确?

 class Drawing(ABC):

    @abstractmethod
    def draw(self):
        pass
    @abstractmethod
    def drawPencil(self):
        pass
    @abstractmethod
    def drawPen(self):
        pass

class Sketch(Drawing):
    
   
    def draw(self):
        print("Drawing a sketch")

    def drawPencil(self):
        print("Drawing with pencil")

    def drawPen(self):
        print("Drawing with pen")
    

【问题讨论】:

    标签: python inheritance abstract-class decorator python-decorators


    【解决方案1】:

    我会作为基类

    from abc import ABCMeta, abstractmethod
    
    class IDrawing(metaclass=ABCMeta):
        
        @staticmethod
        @abstractmethod
        def draw():
            pass
    
    class Sketch(IDrawing):
        #override
        def draw(self):
            print("Drawing a sketch")
    
    r = Sketch()
    r.draw()
    #Drawing a sketch
    
    

    如果此抽象方法不需要任何类实习生属性,则使用@staticmethod。 否则,您使用 @classmethod 并作为第一个参数 cls (因为 abstractmethod 不能使用 self 来引用实例)。 没有@staticmethod 也可以工作...

    现在使用你的 print 函数,我会像这样定义装饰器:

    from abc import ABCMeta, abstractmethod
    
    class IDrawing(metaclass=ABCMeta):
        
        @staticmethod
        @abstractmethod
        def draw():
            pass
    
    def pen(func):
        def new_func(*args, **kwargs):
            func(*args, **kwargs)
            print("with a pen")
        return new_func
    
    def pencil(func):
        def new_func(*args, **kwargs):
            func(*args, **kwargs)
            print("with a pencil")
        return new_func
    
    class Sketch(IDrawing):
        #override
        def draw(self):
            print("Drawing a sketch")
        
        @pen
        def drawPen(self):
            print("Drawing ", end="")
        
        @pencil
        def drawPencil(self):
            print("Drawing ", end="")
    
    r = Sketch()
    r.draw()
    r.drawPen()
    r.drawPencil()
    #Drawing a sketch
    #Drawing with a pen
    #Drawing with a pencil
    

    我个人更喜欢返回字符串并在调用它们时使用print 命令的函数。

    
    from abc import ABCMeta, abstractmethod
    
    class IDrawing(metaclass=ABCMeta):
        
        @staticmethod
        @abstractmethod
        def draw():
            pass
    
    def pen(func):
        def new_func(*args, **kwargs):
            return func(*args, **kwargs) + " with a pen"
        return new_func
    
    def pencil(func):
        def new_func(*args, **kwargs):
            return func(*args, **kwargs) + " with a pencil"
        return new_func
    
    class Sketch(IDrawing):
        #override
        def draw(self):
            return "Drawing a sketch"
        
        @pen
        def drawPen(self):
            return "Drawing"
        
        @pencil
        def drawPencil(self):
            return "Drawing"
    
    r = Sketch()
    print(r.draw())
    print(r.drawPen())
    print(r.drawPencil())
    #Drawing a sketch
    #Drawing with a pen
    #Drawing with a pencil
    
    

    【讨论】:

      【解决方案2】:

      你的意思是你想要不同的派生类以不同的方式绘制?

      from abc import ABC, abstractmethod
      
      class Drawing(ABC):
          @abstractmethod
          def draw(self):
              pass
      
      class Sketch(Drawing):
          def draw(self):
              print("Drawing a sketch")
      
      class PencilSketch(Drawing):
          def draw(self):
              print("Drawing with pencil")
      
      class PenSketch(Drawing):
          def draw(self):
              print("Drawing with pen")
      
      drawObjs = [Sketch(), PencilSketch(), PenSketch()]
      for obj in drawObjs:
          obj.draw()
      

      输出:

      Drawing a sketch
      Drawing with pencil
      Drawing with pen
      

      【讨论】:

        猜你喜欢
        • 2012-02-09
        • 1970-01-01
        • 2018-07-14
        • 1970-01-01
        • 2014-01-14
        • 2013-06-23
        • 2021-09-28
        • 2020-01-11
        • 1970-01-01
        相关资源
        最近更新 更多