【问题标题】:add method to a class dynamically with decorator使用装饰器动态地将方法添加到类中
【发布时间】:2012-03-15 16:03:25
【问题描述】:

我会动态地将方法添加到class...函数名也将动态传递。

我该怎么办?我是这样尝试的

def decor(*var):
  def onDecorator(aClass):
    class onInstance:
        def __init__(self,*args,**kargs):
            setter=var
            aClass.setter = self.flam
            self.wrapped = aClass(*args,**kargs)

        def __getattr__(self,attr):
            return getattr(self.wrapped,attr)

        def __setattr__(self,attr,value):
            if attr == 'wrapped':
                self.__dict__[attr]=value
            else:
                setattr(self.wrapped,attr,value)

        def flam(self,*args):
            self.__setattr__('dimension',len(args[0]))

    return onInstance
return onDecorator

但如果我这样做:

print(aClass.__dict__)

我有

'setter': <bound method onInstance.flam of <__main__.onInstance object at 0x522270>>

而不是var:.....

我有这门课:

class D:
  def __init__(self, data):
    self.data = data
    self.dimension = len(self.data)

我会打电话给:

D.name()

已经回复self.dimension,但我不知道提前name

【问题讨论】:

  • 显示您希望用于将方法附加到类的代码示例。我不知道您如何拥有要附加的方法,但没有任何名称。我也不知道如果该类最初不是使用该方法设计的,那么您希望该方法如何有意义地附加到该类。
  • 多年后,但展示了一个很好且简单的解决方案:medium.com/@mgarod/…

标签: python methods decorator


【解决方案1】:

这是我的装饰器

def decorator(name):
    def wrapper(K):
        setattr(K, name, eval(name))
        return K
    return wrapper

这是一个示例方法

def myfunc(self):
    print "Istance class: ", self

这是一个装饰类

@decorator("myfunc")
class Klass:
    pass

我希望这是有用的,你需要什么:)

【讨论】:

    【解决方案2】:

    这是一个简化的 py3 解决方案

    class A(object):
        def a(self):
            print('a')
    
    def add_b(cls):
        def b(self):
            print('b')
    
        setattr(cls, 'b', b)
        return cls
    
    @add_b
    class C(A):
        pass
    
    C().b() # 'b'
    

    【讨论】:

    • 这是这里所有解决方案中最优雅的
    【解决方案3】:
    def add_method(cls):
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                return func(*args, **kwargs)
    
            setattr(cls, func.__name__, wrapper)
            return func
        return decorator
    

    现在你可以像这样使用它了:

    class Foo:
        pass
    
    @add_method(Foo)
    def bar(self, parameter1):
        pass # Do something where self is a class instance
    

    只要记住在要添加到类的函数中有 self 参数。

    【讨论】:

      【解决方案4】:
      def dec(cls):
          setattr(cls, 'c', 0)    # add atr counter to CLS
      
          def __init__(self):
              cls.c += 1  # +1 to CLS, not self!
      
          def get_c(self=None):
              return cls.c    # get current value from CLS
      
      
          setattr(cls, '__init__', __init__)  # add new __init__ IT WILL OVERWRITE original __init__
          setattr(cls, 'get_c', get_c)    # add new method
          return cls
      
      @dec
      class A:
          pass
      
      print(A.c) # 0
      user, _, _ = A(), A(), A()
      user.get_c()  # 3
      

      如果您想保存原始 init 并向 def init

      添加新值
      def __init__(self):
          cls.c += 1  # +1 to CLS, not self!
          cls.__init__
      

      【讨论】:

        猜你喜欢
        • 2013-04-04
        • 2011-07-25
        • 2015-01-03
        • 1970-01-01
        • 1970-01-01
        • 2019-12-24
        • 2018-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多