字面意思上的区别
Attribute与property, 都可翻译成属性
. 虽然无论是在中文中还是英文中 它们的意思都几乎一样, 但仍有些许差别. Google了好几下, 找到了一个看起来比较靠谱的解释:
According to Webster, a property is a characteristic that belongs to a thing’s essential nature and may be used to describe a type or species.
An attribute is a modifier word that serves to limit, identify, particularize, describe, or supplement the meaning of the word it modifies.
简单来说, property是类的本质属性, 可用于定义和描述一个类别或物种; attribute则是用于详细说明它所描述的物体, 是物体的具体属性.
例如: 人都有嘴巴. 有的人嘴巴很大
, 嘴巴
是人的property之一, 而大嘴巴
只能说是部分人的attribute.
从这个意义上讲, property是attribute的子集.
Python里的attribute与property
回到Python.
Attribute与property在Java中不作区分, 但在Python中有所不同. 下面是Fluent Python(Chapter 19)给出的(非正式)定义:
接下来分别解释.
attribute
所有的数据属性(data attribute)与方法(method)都是attribute. 根据attribute的所有者, 可分为class attribute与instance attribute. class或instance的所有attribute都存储在各自的__dict__
属性中.
例如:
# Python3
class Foo():
name = 'Foo class attribute'
def fn(self):
pass
print('class attribute:', Foo.__dict__)
print()
foo = Foo()
foo.name = 'foo instance attribute'
print('instance attribute:', foo.__dict__)
输出:
class attribute: {
'fn': <function Foo.fn at 0x7fd135ec8ea0>, ... , 'name': 'Foo class attribute'}
instance attribute: {
'name': 'foo instance attribute'}
property
property是出于安全考虑用setter/getter方法替代data attribute, 例如, 只读属性与属性值合法性验证.
只读属性
例如:
class Foo():
def __init__(self, name):
self.name = name
foo = Foo('I do not want to be changed')
print('foo.name = ', foo.name)
foo.name = 'Unluckily, I can be changed'
print('foo.name = ', foo.name)
输出:
foo.name = I do not want to be changed
foo.name = Unluckily, I can be changed
在上面的代码中, 假如我们只想将foo的name属性暴露给外部读取, 但并不想它被修改, 我们该怎么办? 之前在Python 定义只读属性中列出了两种解决方案. 第一种方案:”通过私有属性”, 其实就是用property替代attribute.
将上面的foo.name
改写成property:
class Foo():