使用WITH简化多级对象引用,重新混合PASCAL的WITH语句

withref的Python项目详细描述


travisciPyPI Package latest releaseSupported versionsSupported implementationsWheel packaging supportTest line coverageTest branch coverage

withref使python的with语句能够简化复杂的 取消引用。这就是我最初天真地认为的 for,类似于半记忆pascal的with语句。

典型的Python使用是对入口和出口的更复杂的保护 使用对象的点。参见例如this effbot article,但是withref使 更简单的“请给我未被引用的对象”用例工作如下 好。

用法

from __future__ import print_function # Python 2/3 compatibility
from withref import ref
from stuf import stuf

# stuf used for demonstration purposes only. Convenient way to
# make dict entries accessible as dot-deferenceable properties.

a = stuf({ 'b': { 'c': { 'c1': 1 }, 'd': 44.1 } })

with ref(a.b.c) as c:
    c.c1 = 99

print(a)
a_ideal = stuf({'b': {'c': {'c1': 99}, 'd': 44.1}})
assert a == a_ideal

当然,它也适用于数组样式引用:

with ref(a['b']['c']) as cc:
    c['c1'] = 99

assert a == a_ideal

但要小心不要乱引用!当它正常工作时:

with ref(a.b.c.c1) as c1:
    print(c1)
    assert c1 == 99

这不是:

with ref(a.b.c.c1) as c1:
    c1 = 12345
    assert c1 == 12345

assert a.b.c.c1 == 99   # with heavy heart
                        # because we just ostensibly set it to 12345

与pascal不同,ref不是内置到语言中的。与Perl不同的是, python并不急于为每个 提及变量或值。因此,ref可以提供 完全延迟的c1,但不是可分配的l值。

像pascal的with一样,ref删除封闭结构的n-1层 对于值,但对于赋值只有n-2。不过,在复杂的多层结构中 结构,这是一个很好的简化:

with ref(app.config.server.wsgi) as wsgi:
    wsgi.logger = some_logger
    wsgi.debug_level = 4
    wsgi.port = 8080

有争议的节拍:

app.config.server.wsgi.logger = some_logger
app.config.server.wsgi.debug_level = 4
app.config.server.wsgi.port = 8080

为了简单明了。

我看到很多配置代码总是重复相同的长度 多级解引用。这种风格是重复性的(抗干的),并且倾向于 左对齐代码块,这两个代码块都会妨碍程序理解。使用 with语句是一种简单的方法,同时还可以添加一些额外的 视觉结构。

虽然赋值(“左值生产”)并不总是可能的,但仍然有 简单的价值创造可能会有一些有趣的技巧:

with ref("this is a string"[0:4]) as t:
    print(t)

备选方案

虽然yadda.yadda.yadda引用太常见,但也可以 使用更接近的变量赋值:

wsgi = app.config.server.wsgi
wsgi.logger = some_logger
wsgi.debug_level = 4
wsgi.port = 8080

这缺少withref方法的缩进结构,但是 仍然比你在野外经常发现的要好得多。

另请参见

withhacks模块,包括 许多其他有趣的技巧(多行lambdas、新的循环结构等)——但是 还需要byteplay模块 积极反省并咀嚼python字节码(“危险,威尔·罗宾逊! 危险!,并且没有更新到Python2.6之后的版本。所以它不在 货币除了现代Python的尾部之外。

未来可能的扩展

withhacks所示,通过内省,我们可以确定 调用对象,即使在它是其叶节点的边缘情况下也是如此 封闭结构。这不需要任何字节码更改,而且应该 与现代版本的python(如2.7]和3.x)兼容。

这个技巧是否可以简单、轻便、可靠地实现,以及 透明到足以满足那些编写模块的人 需要这种解引用的简化-即复杂的模块经常 在生产环境中使用,可以理解他们不喜欢 引入任何可能的误差源或任何性能阻抗 是关键的开放性问题。

注释

安装

要安装或升级到最新版本:

pip install -U withref

您可能需要在它们前面加上sudo来授权 安装。在没有超级用户权限的环境中,您可能希望 使用pip--user选项,仅为而是单一用户 而不是整个系统。根据您的本地系统配置,您可以 可能还需要特定于版本的安装程序,如pip2pip3

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

推荐PyPI第三方库


热门话题
java提高机器学习Rest服务性能   java反转字符的字符串顺序,并使用构造函数将其放入LinkedList   继承为什么Java不支持在方法签名中添加“throws”?   执行DDL alter table if exists任务时发生java错误。城市   java在eclipse中使用CREATETXT并打包在jar中   java AES256与3DES 256密钥检测   具有两个相同类型字段的java JPA实体   java Webapp日志记录设置被忽略   java KeyEventDispatcher可以在一个应用程序中工作,但不能在另一个应用程序中工作   带有Swing和OpenJDK的java PinchZoom   未涉及java AspectJ注释切入点(对于任何注释类型)   java如何在FuseBAI中获取日志文件详细信息   java在Linux上将wstring转换为jstring