[CPyUG:47631] decorator的另一种写法

classic Classic list List threaded Threaded
25 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[CPyUG:47631] decorator的另一种写法

leopay
一般decorator都是写一个嵌套函数,
def A(func):
    def new_func(*args, **argkw):
        #做一些额外的工作
        return func(*args, **argkw) #调用原函数继续进行处理
    return new_func
@A
def f(args):pass


其实也有另外一种"优雅"点的写法:
def A(func, *args, **argkw):
    #做一些额外的工作
    return func(*args, **argkw) #调用原函数继续进行处理

@A.__get__
def f(args):pass

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:47757] Re: decorator的另一种写法

njin
good idea

在 08-4-16,leopay<[hidden email]> 写道:

> 一般decorator都是写一个嵌套函数,
> def A(func):
>     def new_func(*args, **argkw):
>         #做一些额外的工作
>         return func(*args, **argkw) #调用原函数继续进行处理
>     return new_func
> @A
> def f(args):pass
>
>
> 其实也有另外一种"优雅"点的写法:
>  def A(func, *args, **argkw):
>     #做一些额外的工作
>     return func(*args, **argkw) #调用原函数继续进行处理
>
> @A.__get__
> def f(args):pass
>
>  >
>


--
Best Regards,
    Niu Jin

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:47760] Re: decorator的另一种写法

Zoom.Quiet
In reply to this post by leopay
有启发!收藏!
http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17


2008/4/16 leopay <[hidden email]>:

> 一般decorator都是写一个嵌套函数,
> def A(func):
>     def new_func(*args, **argkw):
>         #做一些额外的工作
>         return func(*args, **argkw) #调用原函数继续进行处理
>     return new_func
> @A
> def f(args):pass
>
>
> 其实也有另外一种"优雅"点的写法:
>  def A(func, *args, **argkw):
>     #做一些额外的工作
>     return func(*args, **argkw) #调用原函数继续进行处理
>
> @A.__get__
> def f(args):pass
>
>  >
>



--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:47761] Re: decorator的另一种写法

njin
大妈真的很勤劳啊~~~

在 08-4-17,Zoom. Quiet<[hidden email]> 写道:

> 有启发!收藏!
>  http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17
>
>
>  2008/4/16 leopay <[hidden email]>:
>
> > 一般decorator都是写一个嵌套函数,
>  > def A(func):
>  >     def new_func(*args, **argkw):
>  >         #做一些额外的工作
>  >         return func(*args, **argkw) #调用原函数继续进行处理
>  >     return new_func
>  > @A
>  > def f(args):pass
>  >
>  >
>  > 其实也有另外一种"优雅"点的写法:
>  >  def A(func, *args, **argkw):
>  >     #做一些额外的工作
>  >     return func(*args, **argkw) #调用原函数继续进行处理
>  >
>  > @A.__get__
>  > def f(args):pass
>  >
>  >  >
>  >
>
>
>
>  --
>
> '''过程改进乃是开始催生可促生靠谱的人的组织!
>  PI keeps evolving organizations which promoting people be good!
>  '''http://zoomquiet.org
>  Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
>  Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
>  You can get the truely Freedom 4 software.
>
>
>  >
>


--
Best Regards,
    Niu Jin

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:47762] Re: decorator的另一种写法

haur
确实,相当的酷~~~~~

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:47765] Re: decorator的另一种写法

Zoom.Quiet
In reply to this post by njin
2008/4/17 njin <[hidden email]>:
> 大妈真的很勤劳啊~~~
>
顺手而,
积少成多,聚沙成塔,
坚持积累,终入自在!

>  在 08-4-17,Zoom. Quiet<[hidden email]> 写道:
>
> > 有启发!收藏!
>  >  http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17
>  >
>  >
>  >  2008/4/16 leopay <[hidden email]>:
>  >
>  > > 一般decorator都是写一个嵌套函数,
>  >  > def A(func):
>  >  >     def new_func(*args, **argkw):
>  >  >         #做一些额外的工作
>  >  >         return func(*args, **argkw) #调用原函数继续进行处理
>  >  >     return new_func
>  >  > @A
>  >  > def f(args):pass
>  >  >
>  >  >
>  >  > 其实也有另外一种"优雅"点的写法:
>  >  >  def A(func, *args, **argkw):
>  >  >     #做一些额外的工作
>  >  >     return func(*args, **argkw) #调用原函数继续进行处理
>  >  >
>  >  > @A.__get__
>  >  > def f(args):pass
>  >  >
>  >  >  >
>  >  >
>  >
>  >
>  >
>  >  --
>  >
>
> > '''过程改进乃是开始催生可促生靠谱的人的组织!
>  >  PI keeps evolving organizations which promoting people be good!
>  >  '''http://zoomquiet.org
>  >  Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
>  >  Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
>  >  You can get the truely Freedom 4 software.
>  >
>  >
>  >  >
>  >
>
>
>  --
>  Best Regards,
>     Niu Jin
>
>
>
>  >
>



--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:/] Re: decorator的另一种写法

Robert Chen
有意思,有时间分析分析怎么完成的...

2008/4/17 Zoom. Quiet <[hidden email]>:
2008/4/17 njin <[hidden email]>:
> 大妈真的很勤劳啊~~~
>
顺手而,
积少成多,聚沙成塔,
坚持积累,终入自在!

>  在 08-4-17,Zoom. Quiet<[hidden email]> 写道:
>
> > 有启发!收藏!
>  >  http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17
>  >
>  >
>  >  2008/4/16 leopay <[hidden email]>:
>  >
>  > > 一般decorator都是写一个嵌套函数,
>  >  > def A(func):
>  >  >     def new_func(*args, **argkw):
>  >  >         #做一些额外的工作
>  >  >         return func(*args, **argkw) #调用原函数继续进行处理
>  >  >     return new_func
>  >  > @A
>  >  > def f(args):pass
>  >  >
>  >  >
>  >  > 其实也有另外一种"优雅"点的写法:
>  >  >  def A(func, *args, **argkw):
>  >  >     #做一些额外的工作
>  >  >     return func(*args, **argkw) #调用原函数继续进行处理
>  >  >
>  >  > @A.__get__
>  >  > def f(args):pass
>  >  >
>  >  >  >
>  >  >
>  >
>  >
>  >
>  >  --
>  >
>
> > '''过程改进乃是开始催生可促生靠谱的人的组织!
>  >  PI keeps evolving organizations which promoting people be good!
>  >  '''http://zoomquiet.org
>  >  Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
>  >  Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
>  >  You can get the truely Freedom 4 software.
>  >
>  >
>  >  >
>  >
>
>
>  --
>  Best Regards,
>     Niu Jin
>
>
>
>  >
>



--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.





--
Robert
关注Python 关注搜索
Dynamic Life----http://blog.csdn.net/balabalamerobert
--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:47993] Re: [CPyUG:/] Re: decorator的另一种写法

Zoom.Quiet
2008/4/18 Robert Chen <[hidden email]>:
> 有意思,有时间分析分析怎么完成的...
>
咔咔咔,你连源代码都看光了,怎么没有注意到这种好事儿?

> 2008/4/17 Zoom. Quiet <[hidden email]>:
>
>
> > 2008/4/17 njin <[hidden email]>:
> > > 大妈真的很勤劳啊~~~
> > >
> > 顺手而,
> > 积少成多,聚沙成塔,
> > 坚持积累,终入自在!
> >
> >
> >
> >
> > >  在 08-4-17,Zoom. Quiet<[hidden email]> 写道:
> > >
> > > > 有启发!收藏!
> > >  >  http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17
> > >  >
> > >  >
> > >  >  2008/4/16 leopay <[hidden email]>:
> > >  >
> > >  > > 一般decorator都是写一个嵌套函数,
> > >  >  > def A(func):
> > >  >  >     def new_func(*args, **argkw):
> > >  >  >         #做一些额外的工作
> > >  >  >         return func(*args, **argkw) #调用原函数继续进行处理
> > >  >  >     return new_func
> > >  >  > @A
> > >  >  > def f(args):pass
> > >  >  >
> > >  >  >
> > >  >  > 其实也有另外一种"优雅"点的写法:
> > >  >  >  def A(func, *args, **argkw):
> > >  >  >     #做一些额外的工作
> > >  >  >     return func(*args, **argkw) #调用原函数继续进行处理
> > >  >  >
> > >  >  > @A.__get__
> > >  >  > def f(args):pass
> > >  >  >
> > >  >  >  >
> > >  >  >
> > >  >
> > >  >
> > >  >
> > >  >  --
> > >  >
> > >
> > > > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > >  >  PI keeps evolving organizations which promoting people be good!
> > >  >  '''http://zoomquiet.org
> > >  >  Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > >  >  Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > >  >  You can get the truely Freedom 4 software.
> > >  >
> > >  >
> > >  >  >
> > >  >
> > >
> > >
> > >  --
> > >  Best Regards,
> > >     Niu Jin
> > >
> > >
> > >
> > >  >
> > >
> >
> >
> >
> > --
> > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > PI keeps evolving organizations which promoting people be good!
> > '''http://zoomquiet.org
> > Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > You can get the truely Freedom 4 software.
> >
> >
> >
> >
> >
> >
>
>
>
> --
> Robert
> 关注Python 关注搜索
> Dynamic Life----http://blog.csdn.net/balabalamerobert
>
>
>  >
>



--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:47997] Re: [CPyUG:/] Re: decorator的另一种写法

Robert Chen
呵呵,所以说学无止境嘛......

2008/4/18 Zoom. Quiet <[hidden email]>:
2008/4/18 Robert Chen <[hidden email]>:
> 有意思,有时间分析分析怎么完成的...
>
咔咔咔,你连源代码都看光了,怎么没有注意到这种好事儿?

> 2008/4/17 Zoom. Quiet <[hidden email]>:
>
>
> > 2008/4/17 njin <[hidden email]>:
> > > 大妈真的很勤劳啊~~~
> > >
> > 顺手而,
> > 积少成多,聚沙成塔,
> > 坚持积累,终入自在!
> >
> >
> >
> >
> > >  在 08-4-17,Zoom. Quiet<[hidden email]> 写道:
> > >
> > > > 有启发!收藏!
> > >  >  http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17
> > >  >
> > >  >
> > >  >  2008/4/16 leopay <[hidden email]>:
> > >  >
> > >  > > 一般decorator都是写一个嵌套函数,
> > >  >  > def A(func):
> > >  >  >     def new_func(*args, **argkw):
> > >  >  >         #做一些额外的工作
> > >  >  >         return func(*args, **argkw) #调用原函数继续进行处理
> > >  >  >     return new_func
> > >  >  > @A
> > >  >  > def f(args):pass
> > >  >  >
> > >  >  >
> > >  >  > 其实也有另外一种"优雅"点的写法:
> > >  >  >  def A(func, *args, **argkw):
> > >  >  >     #做一些额外的工作
> > >  >  >     return func(*args, **argkw) #调用原函数继续进行处理
> > >  >  >
> > >  >  > @A.__get__
> > >  >  > def f(args):pass
> > >  >  >
> > >  >  >  >
> > >  >  >
> > >  >
> > >  >
> > >  >
> > >  >  --
> > >  >
> > >
> > > > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > >  >  PI keeps evolving organizations which promoting people be good!
> > >  >  '''http://zoomquiet.org
> > >  >  Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > >  >  Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > >  >  You can get the truely Freedom 4 software.
> > >  >
> > >  >
> > >  >  >
> > >  >
> > >
> > >
> > >  --
> > >  Best Regards,
> > >     Niu Jin
> > >
> > >
> > >
> > >  >
> > >
> >
> >
> >
> > --
> > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > PI keeps evolving organizations which promoting people be good!
> > '''http://zoomquiet.org
> > Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > You can get the truely Freedom 4 software.
> >
> >
> >
> >
> >
> >
>
>
>
> --
> Robert
> 关注Python 关注搜索
> Dynamic Life----http://blog.csdn.net/balabalamerobert
>
>
>  >
>



--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.





--
Robert
关注Python 关注搜索
Dynamic Life----http://blog.csdn.net/balabalamerobert
--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:47998] Re: [CPyUG:/] Re: decorator的另一种写法

Zoom.Quiet
2008/4/18 Robert Chen <[hidden email]>:
> 呵呵,所以说学无止境嘛......
>
happy learnning ;)

> 2008/4/18 Zoom. Quiet <[hidden email]>:
>
>
> > 2008/4/18 Robert Chen <[hidden email]>:
> > > 有意思,有时间分析分析怎么完成的...
> > >
> > 咔咔咔,你连源代码都看光了,怎么没有注意到这种好事儿?
> >
> >
> >
> >
> > > 2008/4/17 Zoom. Quiet <[hidden email]>:
> > >
> > >
> > > > 2008/4/17 njin <[hidden email]>:
> > > > > 大妈真的很勤劳啊~~~
> > > > >
> > > > 顺手而,
> > > > 积少成多,聚沙成塔,
> > > > 坚持积累,终入自在!
> > > >
> > > >
> > > >
> > > >
> > > > >  在 08-4-17,Zoom. Quiet<[hidden email]> 写道:
> > > > >
> > > > > > 有启发!收藏!
> > > > >  >  http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17
> > > > >  >
> > > > >  >
> > > > >  >  2008/4/16 leopay <[hidden email]>:
> > > > >  >
> > > > >  > > 一般decorator都是写一个嵌套函数,
> > > > >  >  > def A(func):
> > > > >  >  >     def new_func(*args, **argkw):
> > > > >  >  >         #做一些额外的工作
> > > > >  >  >         return func(*args, **argkw) #调用原函数继续进行处理
> > > > >  >  >     return new_func
> > > > >  >  > @A
> > > > >  >  > def f(args):pass
> > > > >  >  >
> > > > >  >  >
> > > > >  >  > 其实也有另外一种"优雅"点的写法:
> > > > >  >  >  def A(func, *args, **argkw):
> > > > >  >  >     #做一些额外的工作
> > > > >  >  >     return func(*args, **argkw) #调用原函数继续进行处理
> > > > >  >  >
> > > > >  >  > @A.__get__
> > > > >  >  > def f(args):pass
> > > > >  >  >
> > > > >  >  >  >
> > > > >  >  >
> > > > >  >
> > > > >  >
> > > > >  >
> > > > >  >  --
> > > > >  >
> > > > >
> > > > > > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > > > >  >  PI keeps evolving organizations which promoting people be good!
> > > > >  >  '''http://zoomquiet.org
> > > > >  >  Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > > > >  >  Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > > > >  >  You can get the truely Freedom 4 software.
> > > > >  >
> > > > >  >
> > > > >  >  >
> > > > >  >
> > > > >
> > > > >
> > > > >  --
> > > > >  Best Regards,
> > > > >     Niu Jin
> > > > >
> > > > >
> > > > >
> > > > >  >
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > > > PI keeps evolving organizations which promoting people be good!
> > > > '''http://zoomquiet.org
> > > > Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > > > Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > > > You can get the truely Freedom 4 software.
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > >
> > >
> > >
> > > --
> >
> > > Robert
> > > 关注Python 关注搜索
> > > Dynamic Life----http://blog.csdn.net/balabalamerobert
> > >
> > >
> > >  >
> > >
> >
> >
> >
> > --
> >
> >
> >
> > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > PI keeps evolving organizations which promoting people be good!
> > '''http://zoomquiet.org
> > Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > You can get the truely Freedom 4 software.
> >
> >
> >
>
>
>
>
> --
> Robert
> 关注Python 关注搜索
> Dynamic Life----http://blog.csdn.net/balabalamerobert
>  >
>



--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48000] Re: [CPyUG:/] Re: decorator的另一种写法

leopay
happy learning
open learning

2008/4/18 Zoom. Quiet <[hidden email]>:
2008/4/18 Robert Chen <[hidden email]>:
> 呵呵,所以说学无止境嘛......
>
happy learnning ;)

> 2008/4/18 Zoom. Quiet <[hidden email]>:
>
>
> > 2008/4/18 Robert Chen <[hidden email]>:
> > > 有意思,有时间分析分析怎么完成的...
> > >
> > 咔咔咔,你连源代码都看光了,怎么没有注意到这种好事儿?
> >
> >
> >
> >
> > > 2008/4/17 Zoom. Quiet <[hidden email]>:
> > >
> > >
> > > > 2008/4/17 njin <[hidden email]>:
> > > > > 大妈真的很勤劳啊~~~
> > > > >
> > > > 顺手而,
> > > > 积少成多,聚沙成塔,
> > > > 坚持积累,终入自在!
> > > >
> > > >
> > > >
> > > >
> > > > >  在 08-4-17,Zoom. Quiet<[hidden email]> 写道:
> > > > >
> > > > > > 有启发!收藏!
> > > > >  >  http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17
> > > > >  >
> > > > >  >
> > > > >  >  2008/4/16 leopay <[hidden email]>:
> > > > >  >
> > > > >  > > 一般decorator都是写一个嵌套函数,
> > > > >  >  > def A(func):
> > > > >  >  >     def new_func(*args, **argkw):
> > > > >  >  >         #做一些额外的工作
> > > > >  >  >         return func(*args, **argkw) #调用原函数继续进行处理
> > > > >  >  >     return new_func
> > > > >  >  > @A
> > > > >  >  > def f(args):pass
> > > > >  >  >
> > > > >  >  >
> > > > >  >  > 其实也有另外一种"优雅"点的写法:
> > > > >  >  >  def A(func, *args, **argkw):
> > > > >  >  >     #做一些额外的工作
> > > > >  >  >     return func(*args, **argkw) #调用原函数继续进行处理
> > > > >  >  >
> > > > >  >  > @A.__get__
> > > > >  >  > def f(args):pass
> > > > >  >  >
> > > > >  >  >  >
> > > > >  >  >
> > > > >  >
> > > > >  >
> > > > >  >
> > > > >  >  --
> > > > >  >
> > > > >
> > > > > > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > > > >  >  PI keeps evolving organizations which promoting people be good!
> > > > >  >  '''http://zoomquiet.org
> > > > >  >  Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > > > >  >  Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > > > >  >  You can get the truely Freedom 4 software.
> > > > >  >
> > > > >  >
> > > > >  >  >
> > > > >  >
> > > > >
> > > > >
> > > > >  --
> > > > >  Best Regards,
> > > > >     Niu Jin
> > > > >
> > > > >
> > > > >
> > > > >  >
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > > > PI keeps evolving organizations which promoting people be good!
> > > > '''http://zoomquiet.org
> > > > Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > > > Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > > > You can get the truely Freedom 4 software.
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > >
> > >
> > >
> > > --
> >
> > > Robert
> > > 关注Python 关注搜索
> > > Dynamic Life----http://blog.csdn.net/balabalamerobert
> > >
> > >
> > >  >
> > >
> >
> >
> >
> > --
> >
> >
> >
> > '''过程改进乃是开始催生可促生靠谱的人的组织!
> > PI keeps evolving organizations which promoting people be good!
> > '''http://zoomquiet.org
> > Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
> > Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
> > You can get the truely Freedom 4 software.
> >
> >
> >
>
>
>
>
> --
> Robert
> 关注Python 关注搜索
> Dynamic Life----http://blog.csdn.net/balabalamerobert
>  >
>



--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.




--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48006] Re: [CPyUG:/] Re: decorator的另一种写法

yuting cui
In reply to this post by Robert Chen
在 08-4-18,Robert Chen<[hidden email]> 写道:
> 有意思,有时间分析分析怎么完成的...
简单看了一下,对于一个函数来说,它的默认的__get__方法是把实例和这个函数绑定
比如说:
py>>> class A(object):
    def __init__(self):
        pass

py>>> A.__dict__['__init__']
<function __init__ at 0x014A77F0>

py>>> a=A()
py>>> a.__dict__['__init__']

Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    a.__dict__['__init__']
KeyError: '__init__'

py>>> a.__init__
<bound method A.__init__ of <__main__.A object at 0x014AA670>>
这个地方按照Python2.5参考手册3.4.2.3所说
相当于调用type(a).__dict__['__init__'].__get__(a,type(a))
为了达到这个目的,function的默认__get__就是把给定参数和该函数绑定并返回一个实例方法(instancemethod)
这样在你调用a.__init__这个instancemethod的时候,就相当于把a作为第一个参数并在后面按顺序添加其他的参数之后传递给__init__这个function

于是,前面那个特殊写法的decorator就很好理解了
@A.__get__
def f(args):pass
这样在调用f(args)的时候,就相当于调用A.__get__(f)(args)
而A.__get__(f)按上述说法相当于一个把f绑定在第一个参数的A
这样A.__get__(f)(args)就等于A(f,args)
完毕

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48030] Re: [CPyUG:/] Re: decorator的另一种写法

Handle Huang
受教育了

在08-4-19,yuting cui <[hidden email]> 写道:
在 08-4-18,Robert Chen<[hidden email]> 写道:
> 有意思,有时间分析分析怎么完成的...
简单看了一下,对于一个函数来说,它的默认的__get__方法是把实例和这个函数绑定
比如说:
py>>> class A(object):
    def __init__(self):
        pass

py>>> A.__dict__['__init__']
<function __init__ at 0x014A77F0>

py>>> a=A()
py>>> a.__dict__['__init__']

Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    a.__dict__['__init__']
KeyError: '__init__'

py>>> a.__init__
<bound method A.__init__ of <__main__.A object at 0x014AA670>>
这个地方按照Python2.5参考手册3.4.2.3所说
相当于调用type(a).__dict__['__init__'].__get__(a,type(a))
为了达到这个目的,function的默认__get__就是把给定参数和该函数绑定并返回一个实例方法(instancemethod)
这样在你调用a.__init__这个instancemethod的时候,就相当于把a作为第一个参数并在后面按顺序添加其他的参数之后传递给__init__这个function

于是,前面那个特殊写法的decorator就很好理解了

@A.__get__
def f(args):pass

这样在调用f(args)的时候,就相当于调用A.__get__(f)(args)
而A.__get__(f)按上述说法相当于一个把f绑定在第一个参数的A
这样A.__get__(f)(args)就等于A(f,args)
完毕



--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48059] Re: [CPyUG:/] Re: decorator的另一种写法

Zoom.Quiet
In reply to this post by yuting cui
追加补充!
http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17


2008/4/19 yuting cui <[hidden email]>:

> 在 08-4-18,Robert Chen<[hidden email]> 写道:
>  > 有意思,有时间分析分析怎么完成的...
>  简单看了一下,对于一个函数来说,它的默认的__get__方法是把实例和这个函数绑定
>  比如说:
>  py>>> class A(object):
>     def __init__(self):
>         pass
>
>  py>>> A.__dict__['__init__']
>  <function __init__ at 0x014A77F0>
>
>  py>>> a=A()
>  py>>> a.__dict__['__init__']
>
>  Traceback (most recent call last):
>   File "<pyshell#47>", line 1, in <module>
>     a.__dict__['__init__']
>  KeyError: '__init__'
>
>  py>>> a.__init__
>  <bound method A.__init__ of <__main__.A object at 0x014AA670>>
>  这个地方按照Python2.5参考手册3.4.2.3所说
>  相当于调用type(a).__dict__['__init__'].__get__(a,type(a))
>  为了达到这个目的,function的默认__get__就是把给定参数和该函数绑定并返回一个实例方法(instancemethod)
>  这样在你调用a.__init__这个instancemethod的时候,就相当于把a作为第一个参数并在后面按顺序添加其他的参数之后传递给__init__这个function
>
>  于是,前面那个特殊写法的decorator就很好理解了
>
> @A.__get__
>  def f(args):pass
>  这样在调用f(args)的时候,就相当于调用A.__get__(f)(args)
>  而A.__get__(f)按上述说法相当于一个把f绑定在第一个参数的A
>  这样A.__get__(f)(args)就等于A(f,args)
>  完毕
>
>
>
>  >
>



--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48069] Re: [CPyUG:/] Re: decorator的另一种写法

OneNew-2

>>> class A(object):
...     pass
>>> a=A()
>>> a.name='old'
>>> def rename(self,s=None):
...     if s==None:
...         print "I'm %s" % self.name
...     else:
...         self.name=s
...         print "Now I'm %s" %s
>>> a.rename=rename.__get__(a)

>>> a.rename()
I'm old
>>> a.rename('young')
Now I'm young

想到一个新的应用:
邪恶的monkey pacth

 
On 4/19/08, Zoom. Quiet <[hidden email]> wrote:
追加补充!
http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17


--
知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能得。

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48071] Re: [CPyUG:/] Re: decorator的另一种写法

Zoom.Quiet
2008/4/19 subowen <[hidden email]>:

> >>> class A(object):
> ...     pass
> >>> a=A()
> >>> a.name='old'
> >>> def rename(self,s=None):
> ...     if s==None:
> ...         print "I'm %s" % self.name
>  ...     else:
> ...         self.name=s
> ...         print "Now I'm %s" %s
> >>> a.rename=rename.__get__(a)
>
> >>> a.rename()
> I'm old
> >>> a.rename('young')
> Now I'm young
> 想到一个新的应用:
> 邪恶的monkey pacth

看来 .__get__ 是类继承过程中内部调用的...

> On 4/19/08, Zoom. Quiet <[hidden email]> wrote:
> >
> > 追加补充!
> > http://wiki.woodpecker.org.cn/moin/MiscItems/2008-04-17
> >
> >
> > --
> > 知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能得。
>


--
'''过程改进乃是开始催生可促生靠谱的人的组织!
PI keeps evolving organizations which promoting people be good!
'''http://zoomquiet.org
Pls. usage OOo to replace M$ Office. http://zh.openoffice.org
Pls. usage 7-zip to replace WinRAR/WinZip. http://7-zip.org
You can get the truely Freedom 4 software.

--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48074] Re: [CPyUG:/] Re: decorator的另一种写法

Robert Chen
In reply to this post by yuting cui
great, 我来添加一点:)

Descriptor
从Python中最简单也最常用的语义表达方式----属性访问----开始。形如obj.name这样的表达形式就是一个属性访问。在Python编译后的结果中,其对应的字节码指令为LOAD_ATTR。属性访问看上去就是一个简单的操作,但是从概念上来说,它分为两个相对独立的部分:
1、属性搜索
2、属性获取
属性搜索就是在对象obj以及obj的各个基类的__dict__中搜索符号"name",当然,这个搜索是有一定顺序的,特别是当基类有多个时,这里不过多深入。一旦发现了符号,就结束了"属性搜索"阶段,从而进入"属性获取"阶段。
最原始的属性获取就是直接取值就好了,比如 value = obj.name,obj中的name对应的是什么东西,value最后也就是什么东西,这种"属性获取"的方式在各种编程语言中都存在,比如Java,C++。这种方式简单,但是不够灵活,比如有一天,我们想要value = obj.name的语义变成"如果name为空,返回一个特殊字符串;否则,返回name本身"。Java和C++无法轻松处理这种潜在的变化,当然,我们可以将代码中所有obj.name改成obj.getName,通过函数完成name的检查,但是一旦工程基本成型后,这种改动的工作量可想而知。所以在Java或C++中,推荐的方式都是将数据设为private,通过public的函数访问属性,当"属性获取"的语义发生改变时,则只需要改变函数即可。比如下面这种方式:
class A {
    private String name;
    public getName() {
        return name;
    }
}
这种方式能够工作,但这意味着,从一开始,我们就必须通过函数包装所有属性,一来这使代码量大大增加;而来obj.getName的表达形式肯定不如obj.name来得自然。所以有了第二种方式,有没有办法,使得只改变class中的一处代码,就使得所有引用obj.name的地方都透明地从简单的赋值语义变为函数调用语义。C#实现了这种方式,Python也通过Descriptor实现了这种方式。
简单地说,当Python在属性搜索结束后,发现符号"name"对应的对象name_obj是一个特殊的descriptor对象时,"属性获取"的语义就从直接返回name_obj变成了return name_obj.__get__(obj, type(obj))。那么什么是一个descriptor对象呢,很简单,一个实现了__get__, __set__, __del__三个特殊函数的class的实例对象就是一个descriptor对象。下面给出一个简单的例子:
class Desc(object):
    def __init__(self, value):
        self.value = value
       
    def __get__(self, obj, type):
        print 'descriptor change something'
        return self.value
       
class A(object):
    pass
   
a = A()
A.value = Desc(1)
print a.value

输出的结果是:
descriptor change something
1

作为Descriptor的函数
有意思的是,一个实现了__get__的class的对象,只有当它是某个class的属性时,才是descriptor,当它是某个instance的属性时,则不是descriptor。比如上面的A.value = Desc(1),换成a.value = Desc(1),那么输出的结果就是<__main__.Desc object at 0x00B46530>了。现在我们可以从另外一个角度来看待函数了,函数是一种descriptor对象,这意味着函数的类中实现了__get__操作。函数还有类?千真万确,在Python中,所有的一切都是对象,所以函数也是一种instance,它的类在Python的源码中对应的是PyFunctionObject。通过下面的代码,我们可以观察到这个PyFunctionObject确实是一个descriptor。
import types
print types.FunctionType.__get__
输出:<slot wrapper '__get__' of 'function' objects>,实际上对应的是Python源码中的func_descr_get函数。
这说明PyFunctionObject确实是一个descriptor,为什么它必须要是一个descriptor呢?答案是为了OO。

function与method
Python中的OO是建立在function的基础上的,这一点跟C++的对象模型很类似。考虑下面的类的定义:
class A(object):
    def show(self, name):
        pirnt 'hello ', name

其中的show仅仅是一个简单的函数,但是你永远不能直接访问这个函数,因为你要访问show,只有两种方式:
1、a = A(); a.show('robert')
2、A.show(A(), 'robert')
无论是a.show,还是A.show,注意,它们都是"属性访问"了。而show这个函数是一种descriptor对象,所以,无论是a.show,还是A.show,都会激发PyFunctionType.__get__(show, obj, type),对于a.show来说,obj,type分别是a和A;而对于A.show来说,obj, type分别为None和A。
但是不管如何,这时我们得到的已经不仅仅是一个函数了,而是经过__get__转换的结果,这个结果是什么呢,是一个method对象,简单地说,这个对象就是将函数,类和实例对象绑定在一起之后得到的一个对象,其中有三个属性,im_func, im_self和im_class,对于PyFunctionType.__get__(show, obj, type)的调用结果而言,存在以下的对应关系:(im_func=show, im_self=obj, im_class=type)。通过descriptor的转换,本来跟谁都没有关系的function,就跟某个对象关联在一起了,这个就是"绑定"。显然,method对象也就一个可调用的对象,当我们进行method(*args, **argkw)的调用时,会被Python转换成im_func(im_self, *args, **argkw)这样的调用,从而实现了OO中"成员函数"的语义。

Decorator
decorator实际上是一种对函数的修饰,比如
def A():
    pass
   
@A
def B():
    pass
编译之后,实际会增加一条对B的动作:B = A(B)。为了将B保存在A的上下文环境中,就使得A必须采用closure的方式。
但是我们看到,实现decorator的关键是保存B,即保存一个函数,我们在上面看到,method对象中恰恰保存了一个函数,于是这一切就顺理成章了。
在之前我们看到descriptor的__get__动作的激发都是由"属性访问"自动激发的,但是我们可以通过A.__get__直接手动激发,所以A.__get__(B)就返回了一个method对象,其中保存了关键的函数B。当我们进行A.__get__(B)(*args, **argkw)这样的调用时,就转换成了A(B, *args, **argkw),本来B这个位置是留给某个实例对象,从而完成"成员函数"语义,实现OO的,但是这仅仅是一种协议,B所占据的位置实际上可以传递进去任意的对象,从而完成任意的操作。
最后我们写出了:
@A.__get__
def B(*args, **argkw):
    pass
这样的形式,让Python编译结果自动为我们完成B = A.__get__(B)的动作,一种"优雅"的decorator形式就诞生了。


2008/4/19 yuting cui <[hidden email]>:
在 08-4-18,Robert Chen<[hidden email]> 写道:
> 有意思,有时间分析分析怎么完成的...
简单看了一下,对于一个函数来说,它的默认的__get__方法是把实例和这个函数绑定
比如说:
py>>> class A(object):
   def __init__(self):
       pass

py>>> A.__dict__['__init__']
<function __init__ at 0x014A77F0>

py>>> a=A()
py>>> a.__dict__['__init__']

Traceback (most recent call last):
 File "<pyshell#47>", line 1, in <module>
   a.__dict__['__init__']
KeyError: '__init__'

py>>> a.__init__
<bound method A.__init__ of <__main__.A object at 0x014AA670>>
这个地方按照Python2.5参考手册3.4.2.3所说
相当于调用type(a).__dict__['__init__'].__get__(a,type(a))
为了达到这个目的,function的默认__get__就是把给定参数和该函数绑定并返回一个实例方法(instancemethod)
这样在你调用a.__init__这个instancemethod的时候,就相当于把a作为第一个参数并在后面按顺序添加其他的参数之后传递给__init__这个function

于是,前面那个特殊写法的decorator就很好理解了
@A.__get__
def f(args):pass
这样在调用f(args)的时候,就相当于调用A.__get__(f)(args)
而A.__get__(f)按上述说法相当于一个把f绑定在第一个参数的A
这样A.__get__(f)(args)就等于A(f,args)
完毕





--
Robert
关注Python 关注搜索
Dynamic Life----http://blog.csdn.net/balabalamerobert
--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48077] Re: [CPyUG:/] Re: decorator的另一种写法

Handle Huang
好文章啊,大妈收了吧

在08-4-19,Robert Chen <[hidden email]> 写道:
great, 我来添加一点:)

Descriptor
从Python中最简单也最常用的语义表达方式----属性访问----开始。形如o<a href="http://bj.name" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">bj.name这样的表达形式就是一个属性访问。在Python编译后的结果中,其对应的字节码指令为LOAD_ATTR。属性访问看上去就是一个简单的操作,但是从概念上来说,它分为两个相对独立的部分:
1、属性搜索
2、属性获取
属性搜索就是在对象obj以及obj的各个基类的__dict__中搜索符号"name",当然,这个搜索是有一定顺序的,特别是当基类有多个时,这里不过多深入。一旦发现了符号,就结束了"属性搜索"阶段,从而进入"属性获取"阶段。
最原始的属性获取就是直接取值就好了,比如 value = obj.name,obj中的name对应的是什么东西,value最后也就是什么东西,这种"属性获取"的方式在各种编程语言中都存在,比如Java,C++。这种方式简单,但是不够灵活,比如有一天,我们想要value = <a href="http://obj.name" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">obj.name的语义变成"如果name为空,返回一个特殊字符串;否则,返回name本身"。Java和C++无法轻松处理这种潜在的变化,当然,我们可以将代码中所有o<a href="http://bj.name" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">bj.name改成obj.getName,通过函数完成name的检查,但是一旦工程基本成型后,这种改动的工作量可想而知。所以在Java或C++中,推荐的方式都是将数据设为private,通过public的函数访问属性,当"属性获取"的语义发生改变时,则只需要改变函数即可。比如下面这种方式:
class A {
    private String name;
    public getName() {
        return name;
    }
}
这种方式能够工作,但这意味着,从一开始,我们就必须通过函数包装所有属性,一来这使代码量大大增加;而来obj.getName的表达形式肯定不如o<a href="http://bj.name" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">bj.name来得自然。所以有了第二种方式,有没有办法,使得只改变class中的一处代码,就使得所有引用o<a href="http://bj.name" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">bj.name的地方都透明地从简单的赋值语义变为函数调用语义。C#实现了这种方式,Python也通过Descriptor实现了这种方式。
简单地说,当Python在属性搜索结束后,发现符号"name"对应的对象name_obj是一个特殊的descriptor对象时,"属性获取"的语义就从直接返回name_obj变成了return name_obj.__get__(obj, type(obj))。那么什么是一个descriptor对象呢,很简单,一个实现了__get__, __set__, __del__三个特殊函数的class的实例对象就是一个descriptor对象。下面给出一个简单的例子:
class Desc(object):
    def __init__(self, value):
        self.value = value
       
    def __get__(self, obj, type):
        print 'descriptor change something'
        return self.value
       
class A(object):
    pass
   
a = A()
A.value = Desc(1)
print a.value

输出的结果是:
descriptor change something
1

作为Descriptor的函数
有意思的是,一个实现了__get__的class的对象,只有当它是某个class的属性时,才是descriptor,当它是某个instance的属性时,则不是descriptor。比如上面的A.value = Desc(1),换成a.value = Desc(1),那么输出的结果就是<__main__.Desc object at 0x00B46530>了。现在我们可以从另外一个角度来看待函数了,函数是一种descriptor对象,这意味着函数的类中实现了__get__操作。函数还有类?千真万确,在Python中,所有的一切都是对象,所以函数也是一种instance,它的类在Python的源码中对应的是PyFunctionObject。通过下面的代码,我们可以观察到这个PyFunctionObject确实是一个descriptor。
import types
print types.FunctionType.__get__
输出:<slot wrapper '__get__' of 'function' objects>,实际上对应的是Python源码中的func_descr_get函数。
这说明PyFunctionObject确实是一个descriptor,为什么它必须要是一个descriptor呢?答案是为了OO。

function与method
Python中的OO是建立在function的基础上的,这一点跟C++的对象模型很类似。考虑下面的类的定义:
class A(object):
    def show(self, name):
        pirnt 'hello ', name

其中的show仅仅是一个简单的函数,但是你永远不能直接访问这个函数,因为你要访问show,只有两种方式:
1、a = A(); a.show('robert')
2、A.show(A(), 'robert')
无论是a.show,还是A.show,注意,它们都是"属性访问"了。而show这个函数是一种descriptor对象,所以,无论是a.show,还是A.show,都会激发PyFunctionType.__get__(show, obj, type),对于a.show来说,obj,type分别是a和A;而对于A.show来说,obj, type分别为None和A。
但是不管如何,这时我们得到的已经不仅仅是一个函数了,而是经过__get__转换的结果,这个结果是什么呢,是一个method对象,简单地说,这个对象就是将函数,类和实例对象绑定在一起之后得到的一个对象,其中有三个属性,im_func, im_self和im_class,对于PyFunctionType.__get__(show, obj, type)的调用结果而言,存在以下的对应关系:(im_func=show, im_self=obj, im_class=type)。通过descriptor的转换,本来跟谁都没有关系的function,就跟某个对象关联在一起了,这个就是"绑定"。显然,method对象也就一个可调用的对象,当我们进行method(*args, **argkw)的调用时,会被Python转换成im_func(im_self, *args, **argkw)这样的调用,从而实现了OO中"成员函数"的语义。

Decorator
decorator实际上是一种对函数的修饰,比如
def A():
    pass
   
@A
def B():
    pass
编译之后,实际会增加一条对B的动作:B = A(B)。为了将B保存在A的上下文环境中,就使得A必须采用closure的方式。
但是我们看到,实现decorator的关键是保存B,即保存一个函数,我们在上面看到,method对象中恰恰保存了一个函数,于是这一切就顺理成章了。
在之前我们看到descriptor的__get__动作的激发都是由"属性访问"自动激发的,但是我们可以通过A.__get__直接手动激发,所以A.__get__(B)就返回了一个method对象,其中保存了关键的函数B。当我们进行A.__get__(B)(*args, **argkw)这样的调用时,就转换成了A(B, *args, **argkw),本来B这个位置是留给某个实例对象,从而完成"成员函数"语义,实现OO的,但是这仅仅是一种协议,B所占据的位置实际上可以传递进去任意的对象,从而完成任意的操作。
最后我们写出了:
@A.__get__
def B(*args, **argkw):
    pass
这样的形式,让Python编译结果自动为我们完成B = A.__get__(B)的动作,一种"优雅"的decorator形式就诞生了。


2008/4/19 yuting cui <[hidden email]>:
在 08-4-18,Robert Chen<[hidden email]> 写道:
> 有意思,有时间分析分析怎么完成的...
简单看了一下,对于一个函数来说,它的默认的__get__方法是把实例和这个函数绑定
比如说:
py>>> class A(object):
   def __init__(self):
       pass

py>>> A.__dict__['__init__']
<function __init__ at 0x014A77F0>

py>>> a=A()
py>>> a.__dict__['__init__']

Traceback (most recent call last):
 File "<pyshell#47>", line 1, in <module>
   a.__dict__['__init__']
KeyError: '__init__'

py>>> a.__init__
<bound method A.__init__ of <__main__.A object at 0x014AA670>>
这个地方按照Python2.5参考手册3.4.2.3所说
相当于调用type(a).__dict__['__init__'].__get__(a,type(a))
为了达到这个目的,function的默认__get__就是把给定参数和该函数绑定并返回一个实例方法(instancemethod)
这样在你调用a.__init__这个instancemethod的时候,就相当于把a作为第一个参数并在后面按顺序添加其他的参数之后传递给__init__这个function

于是,前面那个特殊写法的decorator就很好理解了
@A.__get__
def f(args):pass
这样在调用f(args)的时候,就相当于调用A.__get__(f)(args)
而A.__get__(f)按上述说法相当于一个把f绑定在第一个参数的A
这样A.__get__(f)(args)就等于A(f,args)
完毕





--
Robert
关注Python 关注搜索
Dynamic Life----<a href="http://blog.csdn.net/balabalamerobert" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">http://blog.csdn.net/balabalamerobert



--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

vcc
Reply | Threaded
Open this post in threaded view
|

[CPyUG:48084] Re: [CPyUG:/] Re: decorator的另一种写法

vcc
In reply to this post by Robert Chen
严格说起来这两种方法并不等价,因为在标准的decorator写法:
@A
def B():pass 中是调用了A函数来返回一个函数给B;
@A.__get__
def B():pass 并没有调用A函数,虽然也得到了一个新函数,但是这时没有调用A函数,所以表现是不同(这意味着本来A这时可以做的一些工作不能做了)。
 
从这个意义上说,__get__的方法并不是decorator的另一种写法。
 
vcc
--
http://py3k.cn - 新Python,新人生 ^_^
 
----- Original Message -----
Sent: Saturday, April 19, 2008 10:12 PM
Subject: [CPyUG:48074] Re: [CPyUG:/] Re: decorator的另一种写法

great, 我来添加一点:)

Descriptor
从Python中最简单也最常用的语义表达方式----属性访问----开始。形如obj.name这样的表达形式就是一个属性访问。在Python编译后的结果中,其对应的字节码指令为LOAD_ATTR。属性访问看上去就是一个简单的操作,但是从概念上来说,它分为两个相对独立的部分:
1、属性搜索
2、属性获取
属性搜索就是在对象obj以及obj的各个基类的__dict__中搜索符号"name",当然,这个搜索是有一定顺序的,特别是当基类有多个时,这里不过多深入。一旦发现了符号,就结束了"属性搜索"阶段,从而进入"属性获取"阶段。
最原始的属性获取就是直接取值就好了,比如 value = obj.name,obj中的name对应的是什么东西,value最后也就是什么东西,这种"属性获取"的方式在各种编程语言中都存在,比如Java,C++。这种方式简单,但是不够灵活,比如有一天,我们想要value = obj.name的语义变成"如果name为空,返回一个特殊字符串;否则,返回name本身"。Java和C++无法轻松处理这种潜在的变化,当然,我们可以将代码中所有obj.name改成obj.getName,通过函数完成name的检查,但是一旦工程基本成型后,这种改动的工作量可想而知。所以在Java或C++中,推荐的方式都是将数据设为private,通过public的函数访问属性,当"属性获取"的语义发生改变时,则只需要改变函数即可。比如下面这种方式:
class A {
    private String name;
    public getName() {
        return name;
    }
}
这种方式能够工作,但这意味着,从一开始,我们就必须通过函数包装所有属性,一来这使代码量大大增加;而来obj.getName的表达形式肯定不如obj.name来得自然。所以有了第二种方式,有没有办法,使得只改变class中的一处代码,就使得所有引用obj.name的地方都透明地从简单的赋值语义变为函数调用语义。C#实现了这种方式,Python也通过Descriptor实现了这种方式。
简单地说,当Python在属性搜索结束后,发现符号"name"对应的对象name_obj是一个特殊的descriptor对象时,"属性获取"的语义就从直接返回name_obj变成了return name_obj.__get__(obj, type(obj))。那么什么是一个descriptor对象呢,很简单,一个实现了__get__, __set__, __del__三个特殊函数的class的实例对象就是一个descriptor对象。下面给出一个简单的例子:
class Desc(object):
    def __init__(self, value):
        self.value = value
       
    def __get__(self, obj, type):
        print 'descriptor change something'
        return self.value
       
class A(object):
    pass
   
a = A()
A.value = Desc(1)
print a.value

输出的结果是:
descriptor change something
1

作为Descriptor的函数
有意思的是,一个实现了__get__的class的对象,只有当它是某个class的属性时,才是descriptor,当它是某个instance的属性时,则不是descriptor。比如上面的A.value = Desc(1),换成a.value = Desc(1),那么输出的结果就是<__main__.Desc object at 0x00B46530>了。现在我们可以从另外一个角度来看待函数了,函数是一种descriptor对象,这意味着函数的类中实现了__get__操作。函数还有类?千真万确,在Python中,所有的一切都是对象,所以函数也是一种instance,它的类在Python的源码中对应的是PyFunctionObject。通过下面的代码,我们可以观察到这个PyFunctionObject确实是一个descriptor。
import types
print types.FunctionType.__get__
输出:<slot wrapper '__get__' of 'function' objects>,实际上对应的是Python源码中的func_descr_get函数。
这说明PyFunctionObject确实是一个descriptor,为什么它必须要是一个descriptor呢?答案是为了OO。

function与method
Python中的OO是建立在function的基础上的,这一点跟C++的对象模型很类似。考虑下面的类的定义:
class A(object):
    def show(self, name):
        pirnt 'hello ', name

其中的show仅仅是一个简单的函数,但是你永远不能直接访问这个函数,因为你要访问show,只有两种方式:
1、a = A(); a.show('robert')
2、A.show(A(), 'robert')
无论是a.show,还是A.show,注意,它们都是"属性访问"了。而show这个函数是一种descriptor对象,所以,无论是a.show,还是A.show,都会激发PyFunctionType.__get__(show, obj, type),对于a.show来说,obj,type分别是a和A;而对于A.show来说,obj, type分别为None和A。
但是不管如何,这时我们得到的已经不仅仅是一个函数了,而是经过__get__转换的结果,这个结果是什么呢,是一个method对象,简单地说,这个对象就是将函数,类和实例对象绑定在一起之后得到的一个对象,其中有三个属性,im_func, im_self和im_class,对于PyFunctionType.__get__(show, obj, type)的调用结果而言,存在以下的对应关系:(im_func=show, im_self=obj, im_class=type)。通过descriptor的转换,本来跟谁都没有关系的function,就跟某个对象关联在一起了,这个就是"绑定"。显然,method对象也就一个可调用的对象,当我们进行method(*args, **argkw)的调用时,会被Python转换成im_func(im_self, *args, **argkw)这样的调用,从而实现了OO中"成员函数"的语义。

Decorator
decorator实际上是一种对函数的修饰,比如
def A():
    pass
   
@A
def B():
    pass
编译之后,实际会增加一条对B的动作:B = A(B)。为了将B保存在A的上下文环境中,就使得A必须采用closure的方式。
但是我们看到,实现decorator的关键是保存B,即保存一个函数,我们在上面看到,method对象中恰恰保存了一个函数,于是这一切就顺理成章了。
在之前我们看到descriptor的__get__动作的激发都是由"属性访问"自动激发的,但是我们可以通过A.__get__直接手动激发,所以A.__get__(B)就返回了一个method对象,其中保存了关键的函数B。当我们进行A.__get__(B)(*args, **argkw)这样的调用时,就转换成了A(B, *args, **argkw),本来B这个位置是留给某个实例对象,从而完成"成员函数"语义,实现OO的,但是这仅仅是一种协议,B所占据的位置实际上可以传递进去任意的对象,从而完成任意的操作。
最后我们写出了:
@A.__get__
def B(*args, **argkw):
    pass
这样的形式,让Python编译结果自动为我们完成B = A.__get__(B)的动作,一种"优雅"的decorator形式就诞生了。


2008/4/19 yuting cui <[hidden email]>:
在 08-4-18,Robert Chen<[hidden email]> 写道:
> 有意思,有时间分析分析怎么完成的...
简单看了一下,对于一个函数来说,它的默认的__get__方法是把实例和这个函数绑定
比如说:
py>>> class A(object):
   def __init__(self):
       pass

py>>> A.__dict__['__init__']
<function __init__ at 0x014A77F0>

py>>> a=A()
py>>> a.__dict__['__init__']

Traceback (most recent call last):
 File "<pyshell#47>", line 1, in <module>
   a.__dict__['__init__']
KeyError: '__init__'

py>>> a.__init__
<bound method A.__init__ of <__main__.A object at 0x014AA670>>
这个地方按照Python2.5参考手册3.4.2.3所说
相当于调用type(a).__dict__['__init__'].__get__(a,type(a))
为了达到这个目的,function的默认__get__就是把给定参数和该函数绑定并返回一个实例方法(instancemethod)
这样在你调用a.__init__这个instancemethod的时候,就相当于把a作为第一个参数并在后面按顺序添加其他的参数之后传递给__init__这个function

于是,前面那个特殊写法的decorator就很好理解了
@A.__get__
def f(args):pass
这样在调用f(args)的时候,就相当于调用A.__get__(f)(args)
而A.__get__(f)按上述说法相当于一个把f绑定在第一个参数的A
这样A.__get__(f)(args)就等于A(f,args)
完毕





--
Robert
关注Python 关注搜索
Dynamic Life----http://blog.csdn.net/balabalamerobert --~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

[CPyUG:48089] Re: [CPyUG:/] Re: decorator的另一种写法

Robert Chen
当然,__get__与正式的decorator语法本质上根本不同,标准的decorator利用了Python中closure的特性,而__get__则是通过instance method object,内部实现截然不同。然而decorator诞生的初始动力就是提供一种pythonic的修饰函数功能的语法,从duck type的意义上来说,但凡能实现这一点的,称之为decorator也不会引起地球爆炸,宇宙毁灭 :)

2008/4/19 vcc <[hidden email]>:
严格说起来这两种方法并不等价,因为在标准的decorator写法:
@A
def B():pass 中是调用了A函数来返回一个函数给B;
@A.__get__
def B():pass 并没有调用A函数,虽然也得到了一个新函数,但是这时没有调用A函数,所以表现是不同(这意味着本来A这时可以做的一些工作不能做了)。
 
从这个意义上说,__get__的方法并不是decorator的另一种写法。
 
vcc
--
http://py3k.cn - 新Python,新人生 ^_^
 
----- Original Message -----
Sent: Saturday, April 19, 2008 10:12 PM
Subject: [CPyUG:48074] Re: [CPyUG:/] Re: decorator的另一种写法

great, 我来添加一点:)

Descriptor
从Python中最简单也最常用的语义表达方式----属性访问----开始。形如obj.name这样的表达形式就是一个属性访问。在Python编译后的结果中,其对应的字节码指令为LOAD_ATTR。属性访问看上去就是一个简单的操作,但是从概念上来说,它分为两个相对独立的部分:
1、属性搜索
2、属性获取
属性搜索就是在对象obj以及obj的各个基类的__dict__中搜索符号"name",当然,这个搜索是有一定顺序的,特别是当基类有多个时,这里不过多深入。一旦发现了符号,就结束了"属性搜索"阶段,从而进入"属性获取"阶段。
最原始的属性获取就是直接取值就好了,比如 value = obj.name,obj中的name对应的是什么东西,value最后也就是什么东西,这种"属性获取"的方式在各种编程语言中都存在,比如Java,C++。这种方式简单,但是不够灵活,比如有一天,我们想要value = obj.name的语义变成"如果name为空,返回一个特殊字符串;否则,返回name本身"。Java和C++无法轻松处理这种潜在的变化,当然,我们可以将代码中所有obj.name改成obj.getName,通过函数完成name的检查,但是一旦工程基本成型后,这种改动的工作量可想而知。所以在Java或C++中,推荐的方式都是将数据设为private,通过public的函数访问属性,当"属性获取"的语义发生改变时,则只需要改变函数即可。比如下面这种方式:
class A {
    private String name;
    public getName() {
        return name;
    }
}
这种方式能够工作,但这意味着,从一开始,我们就必须通过函数包装所有属性,一来这使代码量大大增加;而来obj.getName的表达形式肯定不如obj.name来得自然。所以有了第二种方式,有没有办法,使得只改变class中的一处代码,就使得所有引用obj.name的地方都透明地从简单的赋值语义变为函数调用语义。C#实现了这种方式,Python也通过Descriptor实现了这种方式。
简单地说,当Python在属性搜索结束后,发现符号"name"对应的对象name_obj是一个特殊的descriptor对象时,"属性获取"的语义就从直接返回name_obj变成了return name_obj.__get__(obj, type(obj))。那么什么是一个descriptor对象呢,很简单,一个实现了__get__, __set__, __del__三个特殊函数的class的实例对象就是一个descriptor对象。下面给出一个简单的例子:
class Desc(object):
    def __init__(self, value):
        self.value = value
       
    def __get__(self, obj, type):
        print 'descriptor change something'
        return self.value
       
class A(object):
    pass
   
a = A()
A.value = Desc(1)
print a.value

输出的结果是:
descriptor change something
1

作为Descriptor的函数
有意思的是,一个实现了__get__的class的对象,只有当它是某个class的属性时,才是descriptor,当它是某个instance的属性时,则不是descriptor。比如上面的A.value = Desc(1),换成a.value = Desc(1),那么输出的结果就是<__main__.Desc object at 0x00B46530>了。现在我们可以从另外一个角度来看待函数了,函数是一种descriptor对象,这意味着函数的类中实现了__get__操作。函数还有类?千真万确,在Python中,所有的一切都是对象,所以函数也是一种instance,它的类在Python的源码中对应的是PyFunctionObject。通过下面的代码,我们可以观察到这个PyFunctionObject确实是一个descriptor。
import types
print types.FunctionType.__get__
输出:<slot wrapper '__get__' of 'function' objects>,实际上对应的是Python源码中的func_descr_get函数。
这说明PyFunctionObject确实是一个descriptor,为什么它必须要是一个descriptor呢?答案是为了OO。

function与method
Python中的OO是建立在function的基础上的,这一点跟C++的对象模型很类似。考虑下面的类的定义:
class A(object):
    def show(self, name):
        pirnt 'hello ', name

其中的show仅仅是一个简单的函数,但是你永远不能直接访问这个函数,因为你要访问show,只有两种方式:
1、a = A(); a.show('robert')
2、A.show(A(), 'robert')
无论是a.show,还是A.show,注意,它们都是"属性访问"了。而show这个函数是一种descriptor对象,所以,无论是a.show,还是A.show,都会激发PyFunctionType.__get__(show, obj, type),对于a.show来说,obj,type分别是a和A;而对于A.show来说,obj, type分别为None和A。
但是不管如何,这时我们得到的已经不仅仅是一个函数了,而是经过__get__转换的结果,这个结果是什么呢,是一个method对象,简单地说,这个对象就是将函数,类和实例对象绑定在一起之后得到的一个对象,其中有三个属性,im_func, im_self和im_class,对于PyFunctionType.__get__(show, obj, type)的调用结果而言,存在以下的对应关系:(im_func=show, im_self=obj, im_class=type)。通过descriptor的转换,本来跟谁都没有关系的function,就跟某个对象关联在一起了,这个就是"绑定"。显然,method对象也就一个可调用的对象,当我们进行method(*args, **argkw)的调用时,会被Python转换成im_func(im_self, *args, **argkw)这样的调用,从而实现了OO中"成员函数"的语义。

Decorator
decorator实际上是一种对函数的修饰,比如
def A():
    pass
   
@A
def B():
    pass
编译之后,实际会增加一条对B的动作:B = A(B)。为了将B保存在A的上下文环境中,就使得A必须采用closure的方式。
但是我们看到,实现decorator的关键是保存B,即保存一个函数,我们在上面看到,method对象中恰恰保存了一个函数,于是这一切就顺理成章了。
在之前我们看到descriptor的__get__动作的激发都是由"属性访问"自动激发的,但是我们可以通过A.__get__直接手动激发,所以A.__get__(B)就返回了一个method对象,其中保存了关键的函数B。当我们进行A.__get__(B)(*args, **argkw)这样的调用时,就转换成了A(B, *args, **argkw),本来B这个位置是留给某个实例对象,从而完成"成员函数"语义,实现OO的,但是这仅仅是一种协议,B所占据的位置实际上可以传递进去任意的对象,从而完成任意的操作。
最后我们写出了:
@A.__get__
def B(*args, **argkw):
    pass
这样的形式,让Python编译结果自动为我们完成B = A.__get__(B)的动作,一种"优雅"的decorator形式就诞生了。


2008/4/19 yuting cui <[hidden email]>:
在 08-4-18,Robert Chen<[hidden email]> 写道:
> 有意思,有时间分析分析怎么完成的...
简单看了一下,对于一个函数来说,它的默认的__get__方法是把实例和这个函数绑定
比如说:
py>>> class A(object):
   def __init__(self):
       pass

py>>> A.__dict__['__init__']
<function __init__ at 0x014A77F0>

py>>> a=A()
py>>> a.__dict__['__init__']

Traceback (most recent call last):
 File "<pyshell#47>", line 1, in <module>
   a.__dict__['__init__']
KeyError: '__init__'

py>>> a.__init__
<bound method A.__init__ of <__main__.A object at 0x014AA670>>
这个地方按照Python2.5参考手册3.4.2.3所说
相当于调用type(a).__dict__['__init__'].__get__(a,type(a))
为了达到这个目的,function的默认__get__就是把给定参数和该函数绑定并返回一个实例方法(instancemethod)
这样在你调用a.__init__这个instancemethod的时候,就相当于把a作为第一个参数并在后面按顺序添加其他的参数之后传递给__init__这个function

于是,前面那个特殊写法的decorator就很好理解了
@A.__get__
def f(args):pass
这样在调用f(args)的时候,就相当于调用A.__get__(f)(args)
而A.__get__(f)按上述说法相当于一个把f绑定在第一个参数的A
这样A.__get__(f)(args)就等于A(f,args)
完毕





--
Robert
关注Python 关注搜索
Dynamic Life----http://blog.csdn.net/balabalamerobert



--
Robert
关注Python 关注搜索
Dynamic Life----http://blog.csdn.net/balabalamerobert
--~--~---------~--~----~------------~-------~--~----~
来自: `python-cn`~ChinesePythonUserGroup 列表
发言: [hidden email] | 退订: [hidden email]
详情: http://groups.google.com/group/python-cn
-~----------~----~----~----~------~----~------~--~---

12