属性,类方法,静态方法
(1)将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
(2)由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class People: def __init__(self,name,age,sex): self.name = name self.__age = age self.__sex = sex @property # property装饰器将类中的方法封装成了属性 def age(self): return self.__age @age.setter # 被 方法名.setter这种装饰器装饰的方法,会在对象对类中的静态变量或属性修改时自动执行的 def age(self,new_age): if type(new_age) is int: self.__age = new_age @age.deleter # 被 方法名.deleter这种装饰器装饰的方法,会在对象对类中的静态变量或属性删除时自动执行的 def age(self): print(self.__age) p = People('eric',33,'男') print(p.age) p.age = 21 # p.age中,p是对象名,age其实是类中的方法名,并不是类中的属性名 print(p.age) del p.age
练习题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Commodity: def __init__(self,name,price,discount): self.name = name self.__price = price self.__disconut = discount @property def price(self): return self.__price * self.__disconut @price.setter def price(self,new_price): self.__price = new_price c = Commodity('banana',7.5,0.4) print(c.price) c.price = 9 print(c.price)
类方法
(1)一般是由类名调用,有些情况,对于类内部的方法,无需对象直接调用,而类名直接调用即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class People: chara = '有思想' def __init__(self,name,age): self.__name = name self.__age = age def drink(self): return '%s正在和水'%self.__name @property def hobby(self): print('%s的爱好是大保健'%self.__name) @classmethod def hobby(cls,now_hobby): cls.__hobby = now_hobby return cls.__hobby p = People('eric',23)、 print(People.hobby('上山砍柴'))
静态方法
(1)不需要传入类名或对象名,直接调用即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Animal: chara = '有意识' @staticmethod def cat(name,sex): print('有一只猫,名字叫%s,它今年有%s岁了,已经很老了' %(name,sex)) Animal.cat('阿花',18)
反射
反射:getattr*****、hasattr*****、setattr**、delattr*的使用
1、反射的概念:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
2、四个可以实现自省的函数(下列方法适用于类和对象,一切皆对象,类本身也是一个对象)
普通情况下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
msg = input('>>>').strip() class Animal: role = '铲屎官' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def cat(self): print('一只大花猫叫阿花') 通过input输入的方式获取一个字符串,然后获取到类中的对应的值,但是普通情况下会有问题 print(Animal.msg) # 报下面的错误 >>>role Traceback (most recent call last): File "C:/Users/admin/PycharmProjects/xu/s22day07/05 反射.py", line 17, in <module> print(Animal.msg) AttributeError: type object 'Animal' has no attribute 'msg' 因为input输入的内容是一个字符串,通过类名.变量名或类名.方法名中.后面的内容不能是字符串类型。 取到值的办法: print(Animal.__dict__[msg]) # __dict__最好只用在通过类名或对象名去查内容,而不是去取值 >>>role 铲屎官
1、在类中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
msg = input('>>>').strip() class Animal: role = '铲屎官' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def cat(self): return '一只大花猫叫阿花' c = Animal('阿花',18,'male') (1)hasattr 判断类中是否有想要的方法 print(hasattr(Animal,'cat')) # True print(hasattr(Animal,'dog')) # True (2)getattr 获取值 print(getattr(Animal,msg)) # getattr的括号中,前面可以是类名,对象名,后面则必须是字符串类型,类中的变量名或者方法名在getattr中都要变成字符串类型,而msg的结果就是一个字符串类型,所以能执行成功。 >>>role 铲屎官 print(getattr(Animal,'cat')(1)) # cat是类中的一个方法,也是一个函数,getattr(Animal,'cat')取到的是cat这个函数的内存地址,后面加个()就能运行,但是因为cat函数里面有个self,所以要随便传一个值给这个self。 (3)hasattr 判断 print(hasattr(Animal,msg)) # True if hasattr(Animal,msg) and msg == 'cat': print(getattr(Animal,msg)(1)) elif hasattr(Animal,msg): print(getattr(Animal, msg)) else: print('输入错误') (4)setattr 增加或修改 setattr(Animal,'arms','AK47') # 增加新值 print(Animal.__dict__) # 查看 'arms': 'AK47' setattr(Animal, 'role', '汪星人') print(Animal.__dict__) 'role': '汪星人', (5)delattr 删除 delattr(Animal,'role') print(Animal.__dict__)
2、对象中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
msg = input('>>>').strip() class Animal: role = '铲屎官' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def cat(self): print('一只大花猫叫阿花') c = Animal('阿花', 18, 'male') (1)getattr getattr(c,msg)() # 加括号执行方法 print(getattr(c,msg)) # 取静态变量的值 (2)hasattr print(hasattr(c,'role')) print(hasattr(c,'cat')) print(hasattr(c,'dog')) # False (3)setattr setattr(c,'name','大黄') print(c.__dict__) {'name': '大黄', 'age': 18, 'sex': 'male'} (4)delattr delattr(c,'sex') print(c.__dict__) {'name': '大黄', 'age': 18, 'sex': 'male'}
3、模块中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import oy # 自定义模块 方式1 a = getattr(oy,'A')() # 取模块中类的内存地址,赋值给一个变量,生成一个对象 getattr(a,'func1')() # 通过对象名执行类里面的方法 print(getattr(a,'role')) # 取变量 方式2 print(getattr(oy,'A').role) # 通过A的内存地址直接加.role取值 getattr(oy,'A').func1(1) # 通过内存地址直接取方法的值 方式3 print(getattr(getattr(oy,'A'),'role')) getattr(getattr(oy,'A'),'func1')(1)
4、当前模块中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
port sys class Animal: role = '铲屎官' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def cat(self): print('一只大猫叫阿花') print(getattr(getattr(sys.modules[__name__],'Animal'),'role')) g = getattr(sys.modules[__name__],'Animal') getattr(g,'cat')(1)