返回介绍

实现细节之二

发布于 2024-01-29 22:24:14 字数 861 浏览 0 评论 0 收藏 0

为了帮助你分析这段代码,这里有一些关于这一版本的最后提示。由于这只是前面小节的示例的泛化,所以那里的大多数提示也适用于这里。

使用__X伪私有名称

除了泛化,这个版本还使用了Python的__X伪私有名称压缩功能(我们在第30章遇到过),来把包装的属性局部化为控制类,通过自动将其作为类名的前缀就可以做到。这避免了前面的版本与一个真实的、包装类可能使用的包装属性冲突的风险,并且它也是一个有用的通用工具。然而,它不是很“私有”,因为压缩的名称可以在类之外自由地使用。注意,在__setattr__中,我们也必须使用完整扩展的名称字符串('_onInstance__wrapped'),因为这是Python对其的修改。

破坏私有

尽管这个例子确实实现了对一个实例及其类的属性的访问控制,它可能以各种方式破坏了这些控制——例如,通过检查包装属性的显式扩展版本(bob.pay可能无效,因为完全压缩的bob._onInstance__wrapped.pay可能会有效)。如果你必须显式地这么做,这些控制可能对于常规使用来说足够了。当然,私有控制通常在任何语言中都会遭到破坏,如果你足够努力地尝试的话(#define private public在某些C++实现中也可能有效)。尽管访问控制可以减少意外修改,但这样的情况大多取决于使用任何语言的程序员。不管何时,源代码可能会被修改,访问控制总是管道流中的一小部分。

装饰器权衡

不用装饰器,我们也可以实现同样的结果,通过使用管理函数或者手动编写装饰器的名称重绑定;然而,装饰器语法使得代码更加一致而明确。这一方法以及任何其他基于包装的方法的主要潜在缺点是,属性访问导致额外调用,并且装饰的类的实例并不真的是最初的装饰类的实例——例如,如果你用X.__class__或isinstance(X,C)测试它们的类型,将会发现它们是包装类的实例。除非你计划在对象类型上进行内省,否则类型问题可能是不相关的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文