day30 Pyhton 面向对象 反射
@property
# 例1 - 1 (某一个属性如果是通过计算得来的,那么计算的过程写在方法里,把这个方法伪装成属性) from math import pi # class Circle: # def __init__(self,r): # self.r = r # # @property # 把一个方法伪装成属性 源码中有人写 # def area(self): # 被property装饰器装饰的方法不能传递除self以外的参数 # return pi*self.r**2 # # @property # def perimeter(self): # return self.r*pi*2 # # c1 = Circle(5) # print(c1.area) # c1.r = 10 # print(c1.area) # 圆c1的面积\周长 # alex的名字 class Circle: def __init__(self,r): self.r = r self.area = pi*self.r**2 self.perimeter = self.r*pi*2 c1 = Circle(5) print(c1.area)#78.53981633974483 c1.r = 10 print(c1.area)#78.53981633974483 area的值在第一次赋值后就固定了 # 例2-1 某一个属性需要被私有化,又需要能被外部查看,这种情况,把这个属性通过方法返回,方法伪装成属性 # class Person: # def __init__(self,name): # self.__name = name # 不让外面随便修改 # def get_name(self): # return self.__name # # alex = Person('alex') # print(alex.get_name())
# 例2-2 # class Person: # def __init__(self,name): # self.__name = name # 不让外面随便修改 # # @property # def name(self): # return self.__name # # alex = Person('alex') # print(alex.name)
# 例2-3 修改属性值 class Person: def __init__(self,name): self.__name = name # 不让外面随便修改 @property def name(self): return self.__name @name.setter # 之前必须有一个同名的方法被property装饰过 def name(self,new_name): if type(new_name) is str: self.__name = new_name @name.deleter def name(self): del self.__name # def set_name(self,new_name): # if type(new_name) is str: # self.__name = new_name alex = Person('alex') print(alex.name) # alex.set_name(123) # print(alex.name) alex.name = 'alex_sb' print(alex.name) del alex.name # 删除name属性 print(alex.name)#'Person' object has no attribute '_Person__name'
# 你有没有什么时候 # 能拿到 字符串 # 你就希望能够通过这个字符串 --> 程序中的变量名(类名\函数名\变量名\方法名\对象名) # class Manager:pass # class Student:pass # class Teacher:pass # identify = 'Student' # print(eval(identify)()) # if 'identify' == 'Manager': # Manager() # elif 'identify' == 'Student': # Student() # elif 'identify' == 'Teacher': # Teacher() # class Person: # role = '人类' # Country = '中国' # # attr = input('>>>') # role 人类 # # # Country 中国 # # print(getattr(Person,'role')) # # print(getattr(Person,'Country')) # if hasattr(Person,attr): # print(getattr(Person,attr)) # if attr == 'role': # print(Person.role) # elif attr == 'Country': # print(Person.Country) # getattr(命名空间,'key') == 命名空间.key # 所有的a.b都可以被反射成getattr(a,'b') # 反射类中的方法 # class Person: # role = '人类' # @staticmethod # def show_courses(): # print('所有课程') # Person.role == getattr(Person,'role') # Person.show_courses() == getattr(Person,'show_courses')() # ret = getattr(Person,'show_courses') # ret() # 有一个类,有很多静态属性,也有很多静态方法/类方法 # 用户输入input任意的属性名或者方法名, # 如果是属性 直接打印 - 用到一个内置函数 # 如果是方法 直接调用 - 用到一个内置函数 # 要求程序不报错
# 什么是封装? # 广义上 # 狭义上 # 类的命名空间(类的对象共享的资源) : # 静态属性 # 类方法 # 静态方法 # 普通方法 # property方法 # 对象的命名空间(对象独有的资源): # 对象的属性 # 对象的方法 # 狭义上 # 私有成员 # 在类的内部 __成员名 # 在类的外部 不能用 # 在存储的空间中 _类名__成员名 # 1.私有成员不能在类的外部使用,也不能被继承 # 无论在哪个类中调用私有成员,一定是在哪个类调,就用哪个类的
# 2.类中的三个装饰器方法 # 先实现功能 # 某个方法如果用到self 传self # 某个方法如果没用到self,用到类 传cls ,加@classmethod装饰器 ***** # 某个方法如果没用到self,没用到类 啥也不传,加@staticmethod装饰器 # 但凡是不需要传self参数的,都不需要实例化,直接使用类调用就可以了 # @property : 伪装一个方法成为一个属性,调用的时候不需要加() # 3.反射 非常重要 # a.b这样的情况 # 如果由于某种原因,b变成了 'b' # 那么就是用getattr(a,'b')的形式获取b对应的值 # 如果b是一个值 那么getattr的结果就是值 # 如果b是一个地址 那么getattr的结果就是地址,地址()就是执行 # from sys import modules # getattr(modules[__name__],'全局变量名') # 从当前文件中寻找全局变量对应的值/地址