python的延迟计算

lazyp的Python项目详细描述


python的延迟计算

这个包实现了一些类似于python的惰性计算的东西- 它是在100%的python代码中实现的。标准安装:

轻松安装lazypy

我在Python2.6下测试并使用它,所以我可以这么说 适用于较新版本。对于老版本,你失去了分叉的未来, 因为从2.6开始,多处理是python的一部分。但它可能 在python 2.3之前的版本中仍然可以使用它。

注意:如果您使用的是0.5之前的版本,那么您使用的是不同的模块名 而不是现在的懒人。我把这个改成了0.5 但是保留了 懒散的评估包名作为旧代码的代理。 不过,这个旧的包名称已被弃用,并将在 未来的版本。一个突破性的变化是 版本仅可用 通过 lazypy 包,而不是旧的兼容包。

什么是懒惰的评价或承诺?

惰性计算是一种封装计算的方法,而实际上 计算它-只有当计算结果 实际上是可以访问的。计算完成后,进一步访问 延迟计算将只返回缓存的结果。

当然,因为python本身不支持惰性计算,而且 解释器中没有足够的钩子来做这样的事情 在python中,这完全是伪造的惰性计算。它实际上做的是 在将强制函数调用结果的对象中包装函数调用 在最晚可能的时刻。

不管发生什么,承诺都应该产生相同的错误消息 你会得到没有承诺-只是代码位置应该是 不同的。应该是这样-但我还不能保证。如果你 注意这样一种情况,一个承诺给出了一些不同于 如遇同样情况,请通知我。

有几种方法可以在代码中获得延迟计算。主要途径 是使用lazy/delay函数或子类lazyevaluated或 使用LazyEvaluationMetaClass作为您自己类的元类。

使用延迟

>>> from LazyEvaluation import delay
>>>
>>> def func(a, b):
...     return a+b
...
>>> res = delay(func, (5, 6))
>>>
>>> print repr(res)
>>> print res

这将在第一个打印语句中打印一个promise实例,然后 第二个打印语句中的数字。这是因为print调用 _对传入的对象(或实际上它使用str内置或 类似的东西-在一些对象上它会调用str 其他人喜欢字符串,它只返回字符串本身即可。

使用lazy

>>> from LazyEvaluation import lazy
>>>
>>> def func(a, b):
...     return a+b
...
>>> func = lazy(func)
>>> print repr(func(5,6))
>>> print func(5,6)

这将在第一次打印时打印promise实例,并在第11次打印时打印 在第二张纸上。函数"lazy"将任何函数转换为它的lazy 当量。它可以在Python2.4及更高版本中用作装饰器。

使用LazyEvaluated

>>> from LazyEvaluation import LazyEvaluated
>>>
>>> class TestClass(LazyEvaluated):
...
...       def test(self, a, b):
...           return a+b
...
>>> print repr(TestClass().test(5,6))
>>> print TestClass().test(5,6)

这将打印结果号。使用懒散的评价会使你的班级 进入一个懒惰的评估类。只有直接属性将转换为 不过,懒惰的评估方法!如果你没有 一个完整的类层次结构,但是只有一个类你想变成某种东西 那就是懒惰。这可能不是最好的方法。

使用LazyEvaluatedMetaClass

>>> from LazyEvaluation import LazyEvaluatedMetaClass
>>>
>>> class TestClass(object):
...
...       __metaclass__ = LazyEvaluatedMetaClass
...
...       def test(self, a, b):
...           return a+b
...
>>> print repr(TestClass().test(5,6))
>>> print TestClass().test(5,6)

这将使类的所有函数属性都变成惰性计算 方法。与上面的样品基本相同,只是没有 使用继承。将子类构建到已经存在的 其直接函数属性计算为惰性的类。

语义上的一些位

python的lazy求值行为与完全lazy的行为有些不同 语言的行为:它并不是完全延迟的评估,而是延迟的 评价。结果必须在最晚的可能时刻进行评估。 为了实现这一点,promise类实现了许多标准的magic方法 并通过首先强制延迟的评估来实现它们(因此 它们的实际值)并将内置方法应用于这些值。

它对二进制运算符方法有特殊处理,因为它首先尝试 调用的主方法,如果该方法不存在或 返回notimplemented,它将使用反向参数运行另一个方法。 这应该适用于使用二进制运算符的大多数情况。

有时,您可能需要在不使用任何 强制计算的常规方法-例如存储强制值 某处。您可以使用force(value)函数进行此操作:

>>> from LazyEvaluation import force
>>>
>>> def anton(a,b):
...     return range(a,b)
...
>>> f = lazy(anton)
>>> l = f(1,10)
>>> l = force(l)
>>> print l

承诺的行为有一个特点 代码中的问题:getattr和setattr不强制它是object! 对promise调用setattr实际上会对promise对象进行setattr 本身,而不是强制的价值。所以如果你在一个承诺上设置了一个属性值 然后强制它,强制值将没有最初的set属性。 其主要原因是promise类中的重载setattr是 相当毛茸茸的-setattr处理所有属性设置,而promise确实有 一些实例变量(=属性)。如果要设置属性 价值观来自承诺,你必须自己去实现它。

如何有新的行为

有时你不需要内置的承诺类承诺。如果你 想要建立自己的,有两种方法:要么只是子类 承诺类,添加您需要的内容或编写您自己的类。

你自己的承诺类必须坚持承诺接口。它必须 定义接受函数、参数列表和 可选参数字典。它必须定义一个 强制进行评估。它必须使用promisetaclass,因为它是__ 因为那一个将填补所有需要的魔术方法。如果需要改变 某些魔术方法的操作方式,就是在本地定义该方法- 元类将自动跳过该预定义方法。

不同行为的一个例子是futures.py模块:它实现了 未来,一个高级并发概念。而不是拖延 计算直到调用force,一个线程开始计算 背景中的结果。如果你试图强求未来,你的电话会 阻止,直到结果就绪。异常被捕获并随后被重新发送, 也是。这允许在代码中使用非常简单的parallism-只需推一些 在后台进行计算,如果在访问时准备好了,则 代码将继续。只有当它还没有填满的时候你才必须 等等。

从懒散的0.3开始,还有forkedfources。他们的行为很像 正常的未来,但在一个单独的过程中运行。这允许编写代码 因为多个进程允许 绕过全局解释器锁。这些分叉的未来利用 在Python2.6中的多处理模块中,因此在旧版本中不可用 python版本(它们的测试用例将在旧版本上失败)。

要使用futures,您可以只使用spawn/future函数对 其行为与delay/lazy-spawn是apply的一个并行版本 future是一个decorator,它将任何可调用的转换为并行版本 本身。要使用forkedFutures,只需将forkedFuture类作为 在这些呼叫中用于将来的类。

还有一对fork/forked函数使用 在违约情况下分叉期货。记住这一点它们都只是句法上的 相同概念的糖-可以互换使用delay、spawn或fork 通过正确的目标类。装潢师也一样。

那该怎么办呢-懒惰,未来还是分叉?

这里有一个关于承诺的三个不同变体的非常简单的摘要 在lazypy中实现,何时使用:

  • 当您想要捕获计算状态时,最好使用delay/lazy 但不是在捕获时运行,而是稍后决定 何时真正计算它(或者根本不计算它)。这个 可能是一些很长的计算,只有在 当你发现一些特殊情况时你的代码。你可以得到 闭包、延迟和延迟的结果非常相似,只是更加一致 习惯用语。
  • 当你有可以与之并行运行的东西时,最好使用spawn/future 计算一些冗长内容的主线程。因为它使用线程 而且由于python有gil,这并不是真正的性能增强。 但是,如果您的主线程主要是等待 计算可以并行运行以准备稍后的结果 需要。
  • 当您需要使用多个核和 希望在主进程旁边运行一些长时间的计算来准备 你以后需要一个结果。由于使用了完整的流程,您可以 充分利用你的多核加速一些计算 可并行化。

一般来说,这三个promise变体都可以通过使用 直接使用底层机制(可以使用 闭包、futures可以通过线程或 直接的多处理模块)。懒散只会给出一个很好的语法 包装器和向其添加并行性或延迟计算的方法 已经准备好的代码-无需更改 代码。如果你以功能性的方式工作的话,它会特别有用 使用python或者如果您想注释现有的类以使其变懒,或者 一些方法的未来语义。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java Spring freemarker多模板加载程序路径   在java插件中从控制台获取输入   java在包中创建继承类   网页抓取Java Jsoup网页抓取   java在线程内创建一个对象,而true条件具有相同的引用   java如何根据空格数拆分字符串   java新的安卓 studio更新中的配置文件“app”是什么?   java在将ArrayList写入/读取到文件时出现奇怪的问题   java Reg替换文本块第一次出现+最后一次出现   java当我单击任何RecyclerView列表项时,如何在MainActivity的EditText中显示特定的单击项?   JAVA XML删除节点仅删除第一个外观   java如何在数组中查找特定值   java SVG/矢量图形对象布尔运算(并集、交集、减法)   java在Android中创建线程需要多长时间   尝试从JBOSS联系Oracle LDAP服务器时发生java连接重置异常   java基于参数获取特定的实现实例   使用java就地修改文件内容   java MonetaryException:未加载MonetaryAmountsSingletonSpi   java接受用户的不同输入并使其触发完全相同的代码段的最短方法是什么   Spring 3.2.8应用程序中未找到java HTTP 404错误