Python学习笔记
类变量和实例变量
类变量与实例变量的定义
- 类变量:在类空间或通过类引用复制的变量
- 实例变量:通过对象引用或self引用赋值的变量
class User:
# 类空间中定义的变量,是类变量
category = "未知类型"
def __init__(self, name = "User", password = "123456"):
# 通过self引用赋值的变量,是实例变量
self.name = name
self.password = password
# 通过类引用赋值的变量,是类变量
User.type = "通用用户"
类、对象可访问类变量
- 通过类,可获取、修改类变量的值;
- 通过对象,可获取类变量的值;
- 如果尝试通过对象为类变量赋值,就变成了新增实例变量。
- 如对于上述程序,可以使用打印语句将其值打印出来
print(User.category)
- 上述语句运行结果是:
通用用户
- 我们也可以通过类来修改类变量的值,如
User.category = "After changed"
print(User.category)
User.type = "Second change"
print(User.category)
print(User.type)
- 这样的运行结果如下:
After changed
After changed
Second change
- 但是如果是通过对象引用类变量,就不能对其进行赋值:
us = User()
# 当对象本身没有category这个实例变量时,对象可访问到类变量
print(us.category)
us.category = "实例类型"
# 当对象本身已有category这个实例变量时,对象优先实例变量,但是这时通过类来访问同名的类变量时,还是访问的“修改前的”类变量
print(us.category)
print(User.category) # 此处访问的依然是类变量
- 上面程序的输出结果是:
未知类型
实例类型
未知类型
- 总结:类不能访问实例变量。
- 实例变量不在类空间下,所以类不能访问实例变量
使用property合成属性
- 使用
property
合成属性相当于实例变量 - 原型:
property(fget=None, fset=None, fdel=None, doc=None)
- 使用
property()
函数定义属性时也可根据需要只传入少量参数,如合成只读属性就无需合成fget
参数
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def getarea(self):
print("getarea实例方法")
return self.width * self.height
# 合成了一个计算面积的属性
area = property(fget = getarea, doc = "获取面积的属性")
def getsize(self):
print("getsize实例方法")
return self.width, self.height
def setsize(self, size):
print("setsize实例方法")
self.width = size[0]
self.height = size[1]
# 合成了一个代表大小的属性
size = property(fget = getsize, fset = setsize, doc = "获取大小的属性")
r = Rectangle(30, 40)
# 访问r的area实例变量,实际上就是调用getarea方法
print(r.area)
# 结果如下:
getarea实例方法
1200
- 我们可以尝试其他的属性(实例方法):
# 访问size属性(实际上就是调用getsize方法)
print(r.size)
# 结果如下:
getsize实例方法
(30, 40)
- 还可以使用函数装饰器 来进行属性的合成:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
# 使用装饰器合成了一个只读属性,此时只读属性名与方法名相同
@property # 由于没有任何参数,默认为只读属性
def getarea(self):
print("getarea方法")
return self.width * self.height
@property
def setsize(self):
print("setsize方法")
return self.width, self.height
@setsize.setter # 这样是装饰出了setter方法
def setsize(self, size):
print("setsize方法")
self.width = size[0]
self.height = size[1]
r = Rectangle(30, 40)
print(r.getarea)
print(r.setsize)
# 结果如下:
getarea方法
1200
setsize方法
(30, 40)