Python学习笔记——面向对象(3)

99封情书 提交于 2020-01-22 07:01:52

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)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!