1. 程式人生 > >關於python當中@修飾符的作用

關於python當中@修飾符的作用

今天看到Python中的一個修飾符'@',不瞭解它的使用,查看了下官方文件,有了一點了解。

不得不佩服老外,治學很嚴謹,在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.

很慚愧,只做了一點微小的工作