Python decorators example

Much of the discussion on comp.lang.python and the python-dev mailing list focuses on the use of decorators as a cleaner way to use the staticmethod() and classmethod() builtins. This capability is much more powerful than that. This section presents some examples of use.

  1. Define a function to be executed at exit. Note that the function isn't actually "wrapped" in the usual sense.

    def onexit(f):
        import atexit
        atexit.register(f)
        return f
    
    @onexit
    def func():
        ...
    

    Note that this example is probably not suitable for real usage, but is for example purposes only.

  2. Define a class with a singleton instance. Note that once the class disappears enterprising programmers would have to be more creative to create more instances. (From Shane Hathaway on python-dev .)

    def singleton(cls):
        instances = {}
        def getinstance():
            if cls not in instances:
                instances[cls] = cls()
            return instances[cls]
        return getinstance
    
    @singleton
    class MyClass:
        ...
    
  3. Add attributes to a function. (Based on an example posted by Anders Munch on python-dev .)

    def attrs(**kwds):
        def decorate(f):
            for k in kwds:
                setattr(f, k, kwds[k])
            return f
        return decorate
    
    @attrs(versionadded="2.2",
           author="Guido van Rossum")
    def mymethod(f):
        ...
    
  4. Enforce function argument and return types. Note that this copies the func_name attribute from the old to the new function. func_name was made writable in Python 2.4a3:

    def accepts(*types):
        def check_accepts(f):
            assert len(types) == f.func_code.co_argcount
            def new_f(*args, **kwds):
                for (a, t) in zip(args, types):
                    assert isinstance(a, t), \
                           "arg %r does not match %s" % (a,t)
                return f(*args, **kwds)
            new_f.func_name = f.func_name
            return new_f
        return check_accepts
    
    def returns(rtype):
        def check_returns(f):
            def new_f(*args, **kwds):
                result = f(*args, **kwds)
                assert isinstance(result, rtype), \
                       "return value %r does not match %s" % (result,rtype)
                return result
            new_f.func_name = f.func_name
            return new_f
        return check_returns
    
    @accepts(int, (int,float))
    @returns((int,float))
    def func(arg1, arg2):
        return arg1 * arg2
    
  5. Declare that a class implements a particular (set of) interface(s). This is from a posting by Bob Ippolito on python-dev based on experience with PyProtocols [27] .

    def provides(*interfaces):
         """
         An actual, working, implementation of provides for
         the current implementation of PyProtocols.  Not
         particularly important for the PEP text.
         """
         def provides(typ):
             declareImplementation(typ, instancesProvide=interfaces)
             return typ
         return provides
    
    class IBar(Interface):
         """Declare something about IBar here"""
    
    @provides(IBar)
    class Foo(object):
            """Implement something here..."""
    

Of course, all these examples are possible today, though without syntactic support.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值