關於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.
很慚愧,只做了一點微小的工作