一,属性: 类似于属性的方法
1,初识属性 : 将方法伪装成属性,虽然在代码层面上没有任何高深之处,但是让其看起来更合理
什么是特性property
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
#例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们 #将其做成一个属性,更便于理解) #成人的BMI数值: #过轻:低于18.5 #正常:18.5-23.9 #过重:24-27 #肥胖:28-32 #非常肥胖, 高于32 # 体质指数(BMI)=体重(kg)÷身高^2(m) # EX:70kg÷(1.75×1.75)=22.86 class People: 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) p1=People('egon',75,1.85) print(p1.bmi)
为什么要用property
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
class Goods(object): def __init__(self): # 原价 self.original_price = 100 # 折扣 self.discount = 0.8 @property def price(self): # 实际价格 = 原价 * 折扣 new_price = self.original_price * self.discount return new_price @price.setter def price(self, value): self.original_price = value @price.deltter def price(self, value): del self.original_price obj = Goods() obj.price # 获取商品价格 obj.price = 200 # 修改商品原价 del obj.price # 删除商品原价
二,类方法,静态方法
方法包括:普通方法,静态方法,和类方法,三种方法在内存中都归属于类,区别在于调用方式不同
普通方法:由对象调用,至少一个self参数,执行普通方法时,自动将调用该方法的对象赋值给self
类方法: 由类调用,至少一个cls参数,执行类方法时,自动将调用该方法的类复制给cls
静态方法: 由类调用,无默认参数
class Foo: def __init__(self, name): self.name = name def ord_func(self): """ 定义普通方法,至少有一个self参数 """ # print self.name print '普通方法' @classmethod def class_func(cls): """ 定义类方法,至少有一个cls参数 """ print '类方法' @staticmethod def static_func(): """ 定义静态方法 ,无默认参数""" print '静态方法' # 调用普通方法 f = Foo() f.ord_func() # 调用类方法 Foo.class_func() # 调用静态方法 Foo.static_func()
相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。
不同点:方法调用者不同、调用方法时自动传入的参数不同
三,反射
通过字符串去操作一个空间
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
hasattr() : 判断此对象中,有没有这个属性
getattr() : 从对象中得到这个属性对应的值
setattr() : 对一个对象的属性进行更改(设置)
delattr() : 对一个对象的属性进行删除
1,实例化一个对象
class Foo: f = '类的静态变量' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name) obj=Foo('egon',73) #检测是否含有某属性 print(hasattr(obj,'name')) print(hasattr(obj,'say_hi')) #获取属性 n=getattr(obj,'name') print(n) func=getattr(obj,'say_hi') func() print(getattr(obj,'aaaaaaaa','不存在啊')) #报错 #设置属性 setattr(obj,'sb',True) setattr(obj,'show_name',lambda self:self.name+'sb') print(obj.__dict__) print(obj.show_name(obj)) #删除属性 delattr(obj,'age') delattr(obj,'show_name') delattr(obj,'show_name111')#不存在,则报错 print(obj.__dict__)
2,类中去研究
#类中去研究 class A: country = 'China' job = 'student' def __init__(self, name, age): self.name = name self.age = age def func(self): print('in func') content = input('>>>') a1 = A("旺财",12) if hasattr(A,content): #查询输入的内容是否在A中 print(getattr(A,content)) #得到输入内容对应的值 print(getattr(A,"func")) else: print("没有...")
3,其他模块去研究
#创建一个oldboy的py文件 class B: name_list = ['张三','旭哥','李四','旭哥'] @staticmethod def add(a,b):return a+b def login(username,password): if username == 'alex' and password == '123': return '登录成功' else: return '登录失败' #不同模块之间执行反射 import oldboy #导入oldboy模块 # bobj = getattr(oldboy,'B') # print(getattr(bobj,"name_list")) print(getattr(oldboy.B,"add")(3,4)) print(getattr(oldboy,"login")("alex","123"))
4,当前模块研究
import sys #引入sys模块(当前的地址) def s1(): print 's1' def s2(): print 's2' this_module = sys.modules[__name__] hasattr(this_module, 's1') getattr(this_module, 's2')