python学习之老男孩python全栈第九期_day026知识点总结——封装、property、类方法、初识反射
一. 封装
class Room: def __init__(self, name, length, width): self.__name = name self.__length = length self.__width = width def get_name(self): return self.__name def set_name(self, newName): if type(newName) is str and newName.isdigit() == False: self.__name = newName else: print('不合法的姓名') def area(self): return self.__length * self.__width jin = Room('金老板的小窝', 5, 10) print(jin.area()) jin.set_name('2') print(jin.get_name())
# 假设父类的私有属性,能被 子类 调用吗? 不能 class Foo: __key = '123' # _Foo__key class Son(Foo): print(Foo.__key) # _Son__key
会用到私有的这个概念的场景 1. 隐藏起一个属性 不想让类的外部调用 2. 我想保护这个属性,不想让属性随意被改变 3. 我想保护这个属性,不被子类继承
二. property
内置装饰器函数,只在面向对象中使用
from math import pi class Circle: def __init__(self, r): self.r = r @property def perimeter(self): return 2 * pi * self.r @property def area(self): return pi * self.r**2 c1 = Circle(10) print(c1.area) # 圆的面积 print(c1.perimeter) # 圆的周长
class Count_bmi: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height @property def bmi(self): return self.weight / (self.height**2) kidd = Count_bmi('KID', 51, 1.68) print(kidd.bmi) kidd.bmi = 23 # 不能改 class Person: def __init__(self, name): self.__name = name @property def name(self): return self.__name + 'SB' @name.setter def name(self, newName): self.__name = newName p = Person('qqq') print(p.name) p.name = 'ppp' print(p.name)
class Goods: # 定义一个超市物品 discount = 0.5 # 全场5折 def __init__(self, name, price): self.name = name self.__price = price @property def price(self): return self.__price * Goods.discount apple = Goods('苹果',4) print(apple.price)
# 属性:查看 修改 删除 # 刚才学了 查看 修改 ,接下来看看怎么删除(不常用) class Person: def __init__(self, name): self.__name = name @property def name(self): return self.__name @name.deleter def name(self): print('执行了这个方法') del self.__name @name.setter def name(self,newName): self.__name = newName p = Person('二哥') print(p.name) del p.name print(p.name) # 在查看就会报错,因为已经删除
三. 类方法
class Goods: # 定义一个超市物品 __discount = 0.5 # 全场5折 def __init__(self, name, price): self.name = name self.__price = price @property def price(self): return self.__price * Goods.__discount @classmethod # 把一个方法变声一个类中的方法,这个方法就直接可以被类调用,不需要依托任何对象 def change_discount(cls, newDiscount): # 修改折扣 cls.__discount = newDiscount apple = Goods('苹果',4) print(apple.price) Goods.change_discount(0.8) # Goods.change_discount(Goods) print(apple.price)
当这个方法的操作只涉及静态属性时,就应该使用calssmethod来装饰这个方法
class Login: def __init__(self, name, password): self.name = name self.password = password def login(self): pass @staticmethod def get_usr_pwd(): # 静态方法 usr = input('用户名:') pwd = input('密码:') Login(usr,pwd) Login.get_usr_pwd()
在完全面向对象的程序中
如果一个函数既和对象没有关系 也和类没有关系 那么就用staticmethod 将这个函数改变成一个静态方法
类方法 和 静态方法 都是类调用的
那么对象可以调用 类方法 和 静态方法 吗? 可以 一般情况下 推荐用类名调用
类方法 有一个默认参数 cls 代表这个类,可以改变这个名字,但不建议改变(与self代表对象似的)
静态方法 没有默认的参数 就像函数一样
四. 初识反射
name = 'alex' class Teacher: dic = { '查看学生信息':'show_student', '查看讲师信息':'show_teacher' } def show_student(self): print('show_student') def show_teacher(self): print('show_teacher') @classmethod def func(self): print('哈哈哈') alex = Teacher() for k in Teacher.dic: print(k) key = input('输入需求:') # print(Teacher.dic[key]) if hasattr(alex,Teacher.dic[key]): func = getattr(alex,Teacher.dic[key]) func() # # alex.show_student() 'show_student' # func = getattr(alex,'show_student') # func() # hasattr getattr delattr # if hasattr(Teacher,'dic'): # ret = getattr(Teacher,'dic') # Teacher.dic # 类也是对象 # ret2 = getattr(Teacher,'func') # 类.方法 Teacher.func # print(ret) # print(ret2) # ret2() # menu = Teacher.dic # # for k in menu: # # print(k)
# 通过反射 # 对象名 获取对象属性 和普通方法 # 类名 获取静态属性 和 类方法 和 静态方法
普通方法 带self
静态方法 @staticmethod
类方法 @classmethod
属性方法 @property