python中的 @ 修饰符

时间:2022-04-02 21:06:31

今天看到Python中的一个修饰符'@',不了解它的使用,查看了下官方文档,有了一点了解。

原文 PEP-318 网址:http://www.python.org/dev/peps/pep-0318/

不得不佩服老外,治学很严谨,在python网站相关网页上把为什么使用decorator(主要为了简便一些代码),以及使用什么字符,甚至语法怎么设计写了个详详细细,好长的一篇啊。

这是查看的其中一篇,我翻译关键部分的一些内容,又摘取一些有用的,有空再翻译。

    @dec2  
@dec1
def func(arg1, arg2, ...):
pass

This is equivalent to(等价于):

 

def func(arg1, arg2, ...):  
pass
func
= dec2(dec1(func))

 

使用示例:

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.

comp.lang.python 和 python-dev的大部分讨论集中在更简捷地使用内置修饰符staticmethod() 和 classmethod() 上。但修饰符的功能远比这强大。下面会对它的使用进行一些讲解:

 

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

1.定义一个执行即退出的函数。注意,这个函数并不像通常情况那样,被真正包裹。
    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 onpython-dev.)

2.定义一个只能产生一个实例的类(有实例后,这个类不能再产生新的实例)。注意,一旦这个类失效了(估计意思是保存在下文的singleton中字典中的相应键失效),就会促使程序员让这个类产生更多的实例。(来自于python-dev的Shane Hathaway)
    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.