翻译:《实用的Python编程》05_02_Classes_encapsulation (2)

使用其它属性时,将会触发错误:

>>> s.price = 385.15 >>> s.prices = 410.2 Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'Stock' object has no attribute 'prices'

管这样可以防止错误和限制对象的使用,但实际上使用 __slots__ 是为了提高性能,提高 Python 利用内存的效率。

关于封装的最终说明

不要滥用私有属性(private attributes),特征属性(properties),插槽属性(slots)等。它们有特殊的用途,你在阅读其它 Python 代码时可能会看到。但是,对于大多数日常编码而言,它们不是必需的。

练习 练习 5.6:简单特征属性

使用特征属性是一种非常有用的给对象添加“计算属性”的方式。虽然你在 stock.py 文件中创建了 Stock 对象,但是请注意,在 Stock 对象上 ,对于不同类型的属性,获取方式稍微有点不同。

>>> from stock import Stock >>> s = Stock('GOOG', 100, 490.1) >>> s.shares 100 >>> s.price 490.1 >>> s.cost() 49010.0 >>>

具体来说,cost 后面之所以要添加括号,是因为 cost 是一个方法。

如果你想去掉 cost() 的括号,那么可以把该方法转为一个特征属性。请修改 Stock 类,使其像下面这样计算所持有股票的总价:

>>> ================================ RESTART ================================ >>> from stock import Stock >>> s = Stock('GOOG', 100, 490.1) >>> s.cost 49010.0 >>>

尝试将 cost作为方法调用(s.cost()),你会发现,现在已经被定义为特征属性的 cost 无法作为方法被调用。

>>> s.cost() ... fails ... >>>

这些更改很可能会破坏你之前的 pcost.py 程序,所以,你可能需要返回到 pcost.py 中去掉 cost() 方法后面的括号()。

练习 5.7:特征属性和 Setters

请修改 shares 属性,以便将该值存储在私有属性中,并且使用属性函数(property functions)确保赋给 shares 的值总是整数。预期行为示例:

>>> ================================ RESTART ================================ >>> from stock import Stock >>> s = Stock('GOOG',100,490.10) >>> s.shares = 50 >>> s.shares = 'a lot' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: expected an integer >>> 练习 5.8:添加插槽属性(slots)

请修改 Stock 类,以便 Stock 类拥有一个 __slots__ 属性。然后确认无法添加新属性:

>>> ================================ RESTART ================================ >>> from stock import Stock >>> s = Stock('GOOG', 100, 490.10) >>> s.name 'GOOG' >>> s.blah = 42 ... see what happens ... >>>

使用 __slots__ 时,Python 使用更高效的对象内部表示。如果你尝试查看实例 s 的底层字典会发生什么?

>>> s.__dict__ ... see what happens ... >>>

应当指出, __slots__ 作为数据结构是类中最常用的一种优化。使用插槽属性使程序占用更少的内存,运行更快。但是,在其它大多数类中,你应该尽可能避免使用 __slots__ 。

注:完整翻译见 https://github.com/codists/practical-python-zh

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxzyp.html