如何在调用构造函数之前使用方法装饰器?

时间:2014-04-07 19:26:27

标签: python python-decorators

我有一些代码允许您定义christmas上发生的事情,而不知道底层实现或方法的调用方式,例如,

# main.py
import lib.person
person = lib.person.Person()

@person.onchristmas()
def christmas():
    print "It's Christmas"

类的实现是这样的:

# lib.person.py
class Person():

  def onchristmas(self):
    def decorator(f):
      self.christmas_handler = f
      return f
    return decorator

  def is_christmas(self):
    # called from somewhere else:
    self.christmas_handler()

问题在于,如果不构建一个人,我就无法导入main.py。同样,我无法将构造函数移动为:

person = None

def init():

    person = lib.person.Person()
    return person

因为那时人是NoneType而装饰者不会工作。这个代码的正确方法是什么:

  1. 我仍然可以使用装饰器让人们在不编辑christmas的情况下实施自己的lib.person.py操作
  2. 我可以使用init()明确构建人员,而不是在导入时发生。
  3. 从评论中进一步详细说明:

    实际上,有很多不同的事情可能不仅仅发生在圣诞节,并且每个动作只有一个处理程序,可能有一个数字,所有必须执行:

    所以:

      def onchristmas(self):
        def decorator(f):
          self.christmas_handler.append(f)
          return f
        return decorator
    
      def is_christmas(self):
          # called from somewhere else:
          for h in self.christmas_handler:
              h()
    

    用法:我希望其他人能够指定一个或多个动作的行为,而不必知道它们将如何/何时被调用,并且理想情况下可以进一步向下注册以便能够取消注册处理程序。

    另外我应该提到只有Person的实例,我不太熟悉Python中的静态方法和单例。谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

问题在于你的装饰师和你的州的混合。为什么不将你的装饰师打破课堂,让你的用户提供他们自己的功能。这样装饰者所依赖的唯一状态就是提供给它的状态。类似的东西:

def christmas_config(user_defined_func):
   def inner_config(func):
       def f(*args, **kwargs):
          print 'Hey Yo'
          return user_defined_func(func, *args, **kwargs)
       return f
   return inner_config

def test(func, *args, **kwargs):
   print 'This is hairy'
   return func(*args, **kwargs)

@christmas_config(test)
def my_func():
   print 'test'

my_func()