在面向对象程序设计思想中,属性还是区分为类属性和实例属性的,但不同的编程语言有不同的定义。
在C++中,类属性是描述类的所有对象共同特征的一个数据项,对于任何对象实例,它的属性值是相同的。正因为不同的编程语言有不同的定义,而有些语言是不区分static类型的,所以并不能用static来表示这个属性是否为类属性。只不过用static修饰的属性可以实现对象间的数据共享而已。
在面向对象的编程语言Python中,类属性就是在类中定义的变量。类属性归类所有,
# 定义一个智能手机类
class SmartPhone(object):
os = "" # 私有属性:系统
type = "" # 私有属性:品牌
memory = "4GB" # 私有属性:内存大小 默认单位GB
# 构造方法
def __init__(self, os, type, memory):
self.os = os
self.ype = type
self.memory = memory
def print_phone_info(self):
print('os:', self.os, '\n品牌:', self.type, '\n内存大小:', self.memory)
这里,根据Python中,类属性的定义:在类中定义的变量
,上面代码有3个类属性:os、type 、memory
。通过类直接访问类属性,也可以通过对象访问类属性。例如:
# 上接
# 通过类直接访问类属性
print('通过类直接访问类属性: ', SmartPhone.os)
print('-------------')
p1 = SmartPhone("iOS 11", "Apple","6GB")
p1.print_phone_info()
# 通过对象也可访问类属性
print('通过对象也可访问类属性os:', p1.os)
运行结果:
通过类直接访问类属性: 系统
-------------
os: iOS 11
品牌: Apple
内存大小: 6GB
通过对象也可访问类属性os: iOS 11
为了简化python中类属性和实例属性,我们重新设计一个类,并给该类设计一个类属性color
:
# 定义一个Car类
class Car(object):
color = 'white'
pass
# 创建Car类的一个实例
c = Car()
# 打印color属性,因为实例并没有color属性,所以会继续查找class的color属性-->打印white
print('1:', c.color)
# 给实例c绑定对象属性color,并赋值:'black'
c.color = "black"
# 打印color属性,由于实例属性优先级比类属性高,因此,它会屏蔽掉类的color属性,打印black
print('2:', c.color)
# 打印类的color属性:white
print('3:', Car.color)
# 删除对象的color属性
del c.color
# 打印color属性,因为实例并没有了color属性,所以会继续查找class的color属性-->打印white
print('4:', c.color)
运行结果:
1: white
2: black
3: white
4: white
可见,当类属性和对象属性同名时,由于实例属性优先级比类属性高,因此,它会屏蔽掉类的同名属性。编写程序的时候,千万不要对实例属性和类属性使用相同的名字。但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。
注意
# 定义一个Car类
class Car(object):
color = 'white'
pass
# 创建Car类的一个实例
c = Car()
# 给实例c绑定对象属性speed,并赋值:200
c.speed = 200
# 创建Car类的一个实例
c2 = Car()
print(c2.speed)
运行结果:
Traceback (most recent call last):
File "F:/python_projects/oop/25Car.py", line 31, in <module>
print(c2.speed)
AttributeError: 'Car' object has no attribute 'speed'
这里的speed
属性只属于c
对象。Car
类中没有speed
类属性,如果该类的其他对象(比如c2)在绑定speed
属性前,则没有该属性,所以直接访问c2.speed
会报错:AttributeError: 'Car' object has no attribute 'speed'
小结
实例属性属于各个实例对象所有,互不干扰;
类属性属于类所有,所有实例共享一个属性;
注意: 不要对实例属性和类属性使用相同的名字,否则将产生覆盖且难以发现的错误。
更多了解,可关注公众号:人人懂编程
微信公众号:人人懂编程
网友评论