python中装饰器类的解释

2024-04-02

在阅读一些 python 模块时,我遇到了这个装饰器类:

# this decorator lets me use methods as both static and instance methods
class omnimethod(object):
        def __init__(self, func):
                self.func = func

        def __get__(self, instance, owner):
                return functools.partial(self.func, instance)

我对装饰器的了解是,可以extend功能(例如函数)。有人可以这么好心地给我解释一下吗why上面的课程很有用并且它到底是如何运作的?

它在代码中的使用方式如下:

@omnimethod:
def some_function(...):
    pass

另一个问题:

I encountered this piece of code in the same file:

@property
def some_other_function(...):
    pass

@property未在文件中的任何位置定义。这是一些标准的装饰器吗?如果是,它有什么作用?谷歌在这个案子上无法帮助我。

顺便说一句,这是我找到代码的来源:http://code.xster.net/pygeocoder/src/c9460febdbd1/pygeocoder.py http://code.xster.net/pygeocoder/src/c9460febdbd1/pygeocoder.py


这个万能方法非常聪明。它使用一些非常微妙的技巧来完成它的工作。让我们从头开始吧。

你可能已经知道了装饰器语法 http://docs.python.org/reference/compound_stmts.html#function-definitions只是函数应用的糖,即:

@somedecorator
def somefunc(...):
    pass

# is the same thing as    

def somefunc(...):
    pass
somefunc = somedecorator(somefunc)

so somefunc实际上是一个omnimethod实例,而不是已定义的函数。有趣的是omnimethod还实施了descriptor界面。 http://docs.python.org/reference/datamodel.html#implementing-descriptors如果一个类属性定义了__get__方法,那么每当提到该属性时,解释器都会调用__get__在该对象上,并返回该对象而不是返回属性本身。

the __get__调用方法时始终将实例作为第一个参数,将该实例的类作为第二个参数。如果属性实际上是从类本身查找的,那么实例将是None.

最后一点诡计是functools.partial http://docs.python.org/library/functools.html#functools.partial,这是Python的函数方式currying http://en.wikipedia.org/wiki/Currying。当你使用partial,你向它传递一个函数和一些参数,它返回一个新函数,当调用该函数时,除了你稍后传入的参数之外,还将使用原始参数调用原始函数。omnimethod使用此技术来填充self它包装的函数的参数。

看起来是这样的。 A常规方法 http://docs.python.org/tutorial/classes.html#method-objects当您从实例读取它时可以调用它,但不能从类本身使用它。你会得到一个未绑定的 TypeError

>>> class Foo(object):
...     def bar(self, baz):
...         print self, baz
... 
>>> f = Foo()
>>> f.bar('apples')
<__main__.Foo object at 0x7fe81ab52f90> apples
>>> Foo.bar('quux')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with 
Foo instance as first argument (got str instance instead)
>>> Foo.bar(None, 'quux')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with
Foo instance as first argument (got NoneType instance instead)
>>> 

Python提供了一个内置的装饰器classmethod http://docs.python.org/library/functions.html#classmethod(并且staticmethod,但没关系),这将允许您在类级别使用它,但它永远不会看到实例。它always接收类作为其第一个参数。

>>> class Foo(object):
...     @classmethod
...     def bar(cls, baz):
...         print cls, baz
... 
>>> f = Foo()
>>> Foo.bar('abc')
<class '__main__.Foo'> abc
>>> f.bar('def')
<class '__main__.Foo'> def
>>> 

凭借着一点小聪明,omnimethod两者兼而有之。

>>> class Foo(object):
...     @omnimethod
...     def bar(self, baz):
...         print self, baz
... 
>>> f = Foo()
>>> Foo.bar('bananas')
None bananas    
>>> f.bar('apples')
<__main__.Foo object at 0x7fe81ab52f90> apples
>>> 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python中装饰器类的解释 的相关文章

随机推荐

  • LinkedHashMap 排序

    正如 LinkedHashMap 的 javadoc 中所指定的 如果将键重新插入到映射中 插入顺序不会受到影响 但在运行下面的程序时 我注意到在更改访问顺序时再次插入相同的键 Map
  • 开源和基于 Web 的 html5 文档查看器 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 无论屏幕分辨率如何,如何使 javascript css 弹出 div 居中?

    我有以下代码 它在禁用背景的同时打开一个新的弹出窗口 问题是我必须将其定位 使其距顶部 100px 已经通过 CSS dialog 获得 并且位于屏幕中央 无论用户的分辨率是多少
  • 如何只允许某些值作为Java方法的参数?

    我想编写一个仅采用某些参数值的方法 例如 f e 在里面ToastAndroid 中的类 你只能使用Toast LENGTH SHORT or Toast LENGTH LONG作为方法的持续时间makeText Context conte
  • 使用 NSLayoutManager 计算每个字形的帧

    在这个线程上 Core Text 在 iOS 中计算字母框架 https stackoverflow com questions 21443625 core text calculate letter frame in ios 他们能够使用
  • DebugDiag 和 MVC4 没有提供可用的堆栈跟踪

    我刚刚在我们的生产服务器上遇到了高 CPU 问题 并决定在本地练习调试此类情况 以便将来为此做好准备 但是当我尝试调试本地 MVC4 站点时 我没有获得与教程相同的信息堆栈跟踪做 问题 有谁知道是否可以获得更多信息的堆栈跟踪 我希望在某个地
  • MKAnnotation - 地图图钉标注在其他地图图钉后面弹出

    我的地图图钉可以非常密集地填充 因此当选择一个图钉时 标注会弹出 但大部分被所有其他地图图钉遮挡 我可以将地图图钉放在前面 它有一个代表选定的地图图钉 不是点击标注 选择引脚 有什么解决方法的建议吗 如果您使用自定义注释视图 您可以为选定的
  • 具有可变列数的 Infragistics XamDataGrid

    我需要能够支持 XamDataGrid 它在设计时不会有一定数量的列 例如 应用程序将运行 从服务器获取一些数据并创建一些对象 根据服务器的响应 每次运行应用程序时可能会有不同数量的对象 这是我的意思的一个例子 假设我调用某个服务并返回带有
  • 添加依赖后无法合并dex

    我收到错误 错误 任务 app transformDexArchiveWithExternalLibsDexMergerForPaidFreeDebug 执行失败 java lang RuntimeException com android
  • 仅在全日历中允许后台事件发生 eventOverlap

    有没有办法避免事件重叠 就像 fullcalendar 配置中的 eventOverlap false 一样 但另一方面允许背景事件重叠 我想将一些事件作为背景事件渲染到我的日历中 就像信息一样 其他日历中已经有一些事件 但允许我在顶部创建
  • 使用 Rally API 通过迭代获取用户故事

    我不知道如何在 Rally 中获取一个用户故事的所有字段 现在 我需要获取最后 5 次迭代 并计算每次迭代的完成点 我设法通过指定来获取迭代type iteration 但不知道如何获取这些迭代的用户故事 以及如何指定仅完成 我应该和Tas
  • Node.js 作为服务,exec 不起作用

    我正在使用 nssm 将 Node js 项目作为服务运行 当用户单击我的 Nodejs 网站上的按钮时 它应该运行require child process exec cmd c batfile bat function res send
  • CakePHP 分页 - 如何从 url 中删除“page:”以获得更好的 seo/更干净的 URL

    当我使用 CakePHP Paging 时 我得到一个像这样的 url http example com php page 2 我必须在控制器 视图和routes php中更改什么才能创建这样的工作网址 http example com p
  • 修改实体框架中实体的属性会导致验证错误

    我试图简单地加载一个实体 修改一个属性 然后将其保存回数据库 var db new NewsletterContext var newsletter db Newsletters Find x gt x ID newsletterID ne
  • AFNetworking POST 请求中的 JSON 数据混乱

    我正在使用 AFNetworking for Objective C 发送请求 当我 NSLog 参数时 这是我发送的对象 games id 50 p 8 ts 0 tt tw 0 ys 35150 yt 156424496 37 4166
  • EventStore 基础知识 - 事件元数据/元数据和事件数据之间有什么区别?

    我刚刚开始使用 理解事件存储 https geteventstore com 或此处可能已知的 get event store 我已经阅读了有关客户 预测和订阅的文档 并准备开始在一些内部项目中使用 我无法完全克服的一件事是 是否有一个指南
  • 有没有办法在 Redis 和关系数据库中使用带有 @RedisHash 的实体?

    我正在使用Spring引导 为了将我的实体保存在关系数据库上 我配置了一个数据源和我的域类 例如 Entity Table schema schema name name tb name public class table name ex
  • Javascript:如何将相同的事件侦听器重新附加到重复出现的元素?

    在我的代码中 我有一个 h1 容器 里面有 h1 元素 如下所示 div h1 Title H1 h1 div 然后 我将一个事件侦听器附加到 h1 元素 以便在用户单击 h1 元素时提醒 h1 文本 var h1 document get
  • Java 8 中函数式接口的用途是什么?

    我在 Java 8 中遇到了一个新术语 函数式接口 我在使用时只能找到它的一种用途lambda 表达式 Java 8提供了一些内置的函数式接口 如果我们想定义任何函数式接口 那么我们可以使用 FunctionalInterface注解 它将
  • python中装饰器类的解释

    在阅读一些 python 模块时 我遇到了这个装饰器类 this decorator lets me use methods as both static and instance methods class omnimethod obje