Python论坛  - 讨论区

标题:[python-chinese] 读书笔记之 python2.4的新东西(1)函数和方法修饰符

2006年01月08日 星期日 13:31

魏忠 weizhong2004 at gmail.com
Sun Jan 8 13:31:06 HKT 2006

5 PEP 318: Decorators for Functions and Methods
函数和方法的修饰符
Python 2.2 extended Python's object model by adding static methods and class
methods, but it didn't extend Python's syntax to provide any new way of
defining static or class methods. Instead, you had to write a def statement
in the usual way, and pass the resulting method to a staticmethod() or
classmethod() function that would wrap up the function as a method of the
new type. Your code would look like this:
python 2.2 通过添加静态方法和类方法扩展了python对象模型,但它并没有提供新的python语法来提供一个定义静态方法或类方法的新路子。
你必须象通常方式那样写一个函数定义语句,然后将该函数作为参数传递给staticmethod()或classmethod()来将其封装成一个新类型的方法。你的代码看起来就象下面这样:
class C:
   def meth (cls):
       ...

   meth = classmethod(meth)   # Rebind name to wrapped-up class method
将属性名重新绑定到封装后的类方法

If the method was very long, it would be easy to miss or forget the
classmethod() invocation after the function body.
如果这个方法定义很长的话,很容易在最后忘记使用classmethod()函数封装该方法。

The intention was always to add some syntax to make such definitions more
readable, but at the time of 2.2's release a good syntax was not obvious.
Today a good syntax still isn't obvious but users are asking for easier
access to the feature; a new syntactic feature has been added to meet this
need.
我们一直很想添加某种语法使这种定义更易读,但是在python2.2发行时,我们还没有想出一个好主意。一直到今天,我们也没有一个特别满意的方案。然而用户迫切需要一种容易点的方法来访问这个新特性,因此添加了函数(方法)修饰符这个特性来满足大家的需要。
The new feature is called ``function decorators''. The name comes from the
idea that classmethod, staticmethod, and friends are storing additional
information on a function object; they're decorating functions with more
details.
这个新特性被称为"函数修饰符"。 这个名字来自 classmethod
staticmethod,大家经常在函数对象中保存附加信息,它们很大程度上修饰了函数细节。
The notation borrows from Java and uses the "@" character as an indicator.
Using the new syntax, the example above would be written:
借用了 JAVA中的 @ 符号来做为指示器。使用新的语法,上面的例子可以被写成这样:

class C:

   @classmethod
   def meth (cls):
       ...

The @classmethod is shorthand for the meth=classmethod(meth) assignment.
More generally, if you have the following:
上例中 @classmethod 是 meth=classmethod(meth) 语句的速记方式,通常,如果你写成下面这样

@A @B @C
def f ():
    ...

It's equivalent to the following pre-decorator code:
它就等同于以下未使用修饰符的语句

def f(): ...
f = A(B(C(f)))

Decorators must come on the line before a function definition, and can't be
on the same line, meaning that @A def f(): ... is illegal. You can only
decorate function definitions, either at the module level or inside a class;
you can't decorate class definitions.
修饰器必须出现在函数定义前一行,不允许和函数定义在同一行。也就是说 @A def f(): 是非法的。
只可以在模块或类定义层内对函数进行修饰,不允许修修饰一个类。

A decorator is just a function that takes the function to be decorated as an
argument and returns either the same function or some new callable thing.
It's easy to write your own decorators. The following simple example just
sets an attribute on the function object:
一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的对象。很容易写出自己的修饰符,下面就是一个简单的例子,它用来设定(被修饰)函数对象的属性。

>>> def deco(func):
...    func.attr = 'decorated'
...    return func
...
>>> @deco
... def f(): pass
...
>>> f

>>> f.attr
'decorated'
>>>

As a slightly more realistic example, the following decorator checks that
the supplied argument is an integer:
一个有点用的小例子:
下面的修饰器检查提供的参数是否为整数

def require_int (func):
    def wrapper (arg):
        assert isinstance(arg, int)
        return func(arg)
    return wrapper

@require_int
def p1 (arg):
    print arg

@require_int
def p2(arg):
    print arg*2

An example in PEP 318 contains a fancier version of this idea that lets you
both specify the required type and check the returned type.
PEP318中的一个例子包含了该主意的一个空想版本,它让你指定你想要的类型并检查返回的类型。
Decorator functions can take arguments. If arguments are supplied, your
decorator function is called with only those arguments and must return a new
decorator function; this function must take a single function and return a
function, as previously described. In other words, @A @B @C(args) becomes:
修饰器函数可以带参数。如果提供了参数,你的修饰器函数被调用时必须返回一个新的修饰器函数,这个新函数必须以一个函数做参数返回另一个函数,就象前面描述的那样。换句话说,@A
@B @C(argc) 将变成

def f(): ...
_deco = C(args)
f = A(B(_deco(f)))

Getting this right can be slightly brain-bending, but it's not too
difficult.
好象比较绕,嘿嘿,但并不很难懂

A small related change makes the func_name attribute of functions writable.
This attribute is used to display function names in tracebacks, so
decorators should change the name of any new function that's constructed and
returned.
一个小的相关变动就是 函数的 func_name 属性由只读变为可写。这个属性通常用来在调试时显示函数的名字。修饰符将会改变新生成的函数的这个属性。



--

开飞机的舒克
http://www.lvye.org/shuke
msn:weizhong at netease.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060108/3ae43836/attachment-0001.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2006年01月10日 星期二 18:35

Davies Liu davies.liu at gmail.com
Tue Jan 10 18:35:16 HKT 2006

很不错,赞一个,前两天看到@符号时还疑惑呢
@deco(argc) 是否可以这样理解:@后面需要跟一个修饰符函数的表达式,该表达式可以直接是函数或者某个函数的调用

davies

在06-1-8,魏忠 <weizhong2004 at gmail.com> 写道:
>
> 5 PEP 318: Decorators for Functions and Methods
> 函数和方法的修饰符
> Python 2.2 extended Python's object model by adding static methods and
> class methods, but it didn't extend Python's syntax to provide any new way
> of defining static or class methods. Instead, you had to write a def
> statement in the usual way, and pass the resulting method to a
> staticmethod() or classmethod() function that would wrap up the function as
> a method of the new type. Your code would look like this:
> python 2.2 通过添加静态方法和类方法扩展了python对象模型,但它并没有提供新的python语法来提供一个定义静态方法或类方法的新路子。
>
> 你必须象通常方式那样写一个函数定义语句,然后将该函数作为参数传递给staticmethod()或classmethod()来将其封装成一个新类型的方法。你的代码看起来就象下面这样:
> class C:
>    def meth (cls):
>        ...
>
>    meth = classmethod(meth)   # Rebind name to wrapped-up class method
> 将属性名重新绑定到封装后的类方法
>
> If the method was very long, it would be easy to miss or forget the
> classmethod() invocation after the function body.
> 如果这个方法定义很长的话,很容易在最后忘记使用classmethod()函数封装该方法。
>
> The intention was always to add some syntax to make such definitions more
> readable, but at the time of 2.2's release a good syntax was not obvious.
> Today a good syntax still isn't obvious but users are asking for easier
> access to the feature; a new syntactic feature has been added to meet this
> need.
>
> 我们一直很想添加某种语法使这种定义更易读,但是在python2.2发行时,我们还没有想出一个好主意。一直到今天,我们也没有一个特别满意的方案。然而用户迫切需要一种容易点的方法来访问这个新特性,因此添加了函数(方法)修饰符这个特性来满足大家的需要。
> The new feature is called ``function decorators''. The name comes from the
> idea that classmethod, staticmethod, and friends are storing additional
> information on a function object; they're decorating functions with more
> details.
> 这个新特性被称为"函数修饰符"。 这个名字来自 classmethod
> staticmethod,大家经常在函数对象中保存附加信息,它们很大程度上修饰了函数细节。
> The notation borrows from Java and uses the "@" character as an indicator.
> Using the new syntax, the example above would be written:
> 借用了 JAVA中的 @ 符号来做为指示器。使用新的语法,上面的例子可以被写成这样:
>
> class C:
>
>    @classmethod
>    def meth (cls):
>        ...
>
> The @classmethod is shorthand for the meth=classmethod(meth) assignment.
> More generally, if you have the following:
> 上例中 @classmethod 是 meth=classmethod(meth) 语句的速记方式,通常,如果你写成下面这样
>
> @A @B @C
> def f ():
>     ...
>
> It's equivalent to the following pre-decorator code:
> 它就等同于以下未使用修饰符的语句
>
> def f(): ...
> f = A(B(C(f)))
>
> Decorators must come on the line before a function definition, and can't
> be on the same line, meaning that @A def f(): ... is illegal. You can only
> decorate function definitions, either at the module level or inside a class;
> you can't decorate class definitions.
> 修饰器必须出现在函数定义前一行,不允许和函数定义在同一行。也就是说 @A def f(): 是非法的。
> 只可以在模块或类定义层内对函数进行修饰,不允许修修饰一个类。
>
> A decorator is just a function that takes the function to be decorated as
> an argument and returns either the same function or some new callable thing.
> It's easy to write your own decorators. The following simple example just
> sets an attribute on the function object:
>
> 一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的对象。很容易写出自己的修饰符,下面就是一个简单的例子,它用来设定(被修饰)函数对象的属性。
>
> >>> def deco(func):
> ...    func.attr = 'decorated'
> ...    return func
> ...
> >>> @deco
> ... def f(): pass
> ...
> >>> f
> 
> >>> f.attr
> 'decorated'
> >>>
>
> As a slightly more realistic example, the following decorator checks that
> the supplied argument is an integer:
> 一个有点用的小例子:
> 下面的修饰器检查提供的参数是否为整数
>
> def require_int (func):
>     def wrapper (arg):
>         assert isinstance(arg, int)
>         return func(arg)
>     return wrapper
>
> @require_int
> def p1 (arg):
>     print arg
>
> @require_int
> def p2(arg):
>     print arg*2
>
> An example in PEP 318 contains a fancier version of this idea that lets
> you both specify the required type and check the returned type.
> PEP318中的一个例子包含了该主意的一个空想版本,它让你指定你想要的类型并检查返回的类型。
> Decorator functions can take arguments. If arguments are supplied, your
> decorator function is called with only those arguments and must return a new
> decorator function; this function must take a single function and return a
> function, as previously described. In other words, @A @B @C(args) becomes:
> 修饰器函数可以带参数。如果提供了参数,你的修饰器函数被调用时必须返回一个新的修饰器函数,这个新函数必须以一个函数做参数返回另一个函数,就象前面描述的那样。换句话说,@A
> @B @C(argc) 将变成
>
> def f(): ...
> _deco = C(args)
> f = A(B(_deco(f)))
>
> Getting this right can be slightly brain-bending, but it's not too
> difficult.
> 好象比较绕,嘿嘿,但并不很难懂
>
> A small related change makes the func_name attribute of functions
> writable. This attribute is used to display function names in tracebacks, so
> decorators should change the name of any new function that's constructed and
> returned.
> 一个小的相关变动就是 函数的 func_name 属性由只读变为可写。这个属性通常用来在调试时显示函数的名字。修饰符将会改变新生成的函数的这个属性。
>
>
>
> --
>
> 开飞机的舒克
> http://www.lvye.org/shuke
> msn:weizhong at netease.com
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
>
>


--
Davies Liu
My Blog: http://blog.daviesliu.net/
My MSN: davies616 at msn.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20060110/07db502e/attachment.htm

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2025

    京ICP备05028076号