反射
反射我们以后会经常用到,这个东西实现了动态的装配,通过字符串来反射类中的属性和方法
反射函数
1、hasarttr(obj,name_str)
作用:判断一个对象obj中是否有对应的name_str字符串的属性或者方法
classDog(object):def __init__(self,name):
self.name=namedefeat(self,food):print("{0} is eating...{1}".format(self.name,food))
d= Dog("shabi")
choice= input(">>>:").strip()print(hasattr(d,choice)) #obj中是否有对应的choice字符串的属性或者方法
#输出
>>>:name #输入对象存在属性
True>>>:eat #输入对象存在的方法
True
View Code
2、getattr(obj,name_str)
作用:根据字符串name_str获取obj对象中的对应方法的内存地址或者对应属性的值
classDog(object):def __init__(self,name):
self.name=namedefeat(self,food):print("{0} is eating...{1}".format(self.name,food))
d= Dog("shabi")
choice= input(">>>:").strip()print(getattr(d,choice)) #choice获取obj对象中的对应方法的内存地址或者对应属性的值
#输出
>>>:name #返回name属性的值
shabi>>>:eat> #返回eat方法的内存地址
View Code
3、setattr(x,y,z)
作用:给obj对象添加一个新属性或者新方法,setattr(x, 'y', v) is equivalent to ``x.y = v''
①给对象新增一个新方法
def bulk(self): #先定义一个bulk函数
print("{0} is yelling...".format(self.name))classDog(object):def __init__(self,name):
self.name=namedefeat(self,food):print("{0} is eating...{1}".format(self.name,food))
d= Dog("shabi")
choice= input(">>>:").strip()
setattr(d,choice,bulk)#输入的是talk,所以又等同于d.talk = bulk#d.talk(d) 直接写死,用d.talk(d),一般不这么写
func = getattr(d,choice) #用getattr来获取
func(d)#输出
>>>:talk
shabiis yelling...
View Code
②给对象新增一个属性
classDog(object):def __init__(self,name):
self.name=namedefeat(self,food):print("{0} is eating...{1}".format(self.name,food))
d= Dog("shabi")
choice= input(">>>:").strip()
setattr(d,choice,22) #输入的是age,所以又等同于d.age = 22#print(d.age) 这样就写死了,还是用下面一种
print(getattr(d,choice))#输出
>>>:age22
View Code
4、delattr(x,y)
作用:删除obj对象中的属性或者方法,delattr(x, 'y') is equivalent to ``del x.y''
classDog(object):def __init__(self,name):
self.name=namedefeat(self,food):print("{0} is eating...{1}".format(self.name,food))
d= Dog("shabi")
choice= input(">>>:").strip()
delattr(d,choice)#根据字符串删除属性或者方法
print(d.name)print(d.eat)#输出
>>>:name #删除属性name
Traceback (most recent call last):print(d.name)
AttributeError:'Dog' object has no attribute 'name'
>>>:eat #删除方法eat
Traceback (most recent call last):
delattr(d,choice)
AttributeError: eat
View Code
5、综合使用hasattr、getattr、setattr
classDog(object):def __init__(self,name):
self.name=namedefeat(self,food):print("{0} is eating...{1}".format(self.name,food))
d= Dog("shabi")
choice= input(">>>:").strip()if hasattr(d,choice): #判断d对象中存在属性和方法
name_value = getattr(d,choice) #获取属性值
print(name_value)
setattr(d,choice,"hong") #修改属性值
print(getattr(d,choice)) #重新获取属性的值
else:
setattr(d,choice,None)#设置不存在的属性值为None
v =getattr(d,choice)print(v)#输出
>>>:name
shabi
hong>>>:abc
None
View Code
创建
前面的随笔都是关于类的知识,通过类创建对象,那这个类到底是怎么产生的呢?
1、 传统创建类
classFoo(object):def __init__(self,name):
self.name=name
f= Foo("shuaigaogao")
View Code
f 是通过 Foo 类实例化的对象,其实,不仅 f 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象,按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的构造方法创建。
print(type(f)) #输出: 表示:f 对象由Foo类创建
print(type(Foo)) #输出: 表示:Foo类对象由 type 类创建
所以,f 对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建
2 、type创建类
说明: type创建类的格式,类名 = type('类名',(父类,),{'方法名':方法的内存地址})
def func(self): #创建方法
print("hello {0}".format(self.name))def __init__(self,name): #创建构造方法
self.name =name#通过type创建类,如果是经典类的话则写成:Foo = type("Foo",(),{"talk":func,"__init__":__init__})
Foo = type("Foo",(object,),{"talk":func,"__init__":__init__})
f= Foo("shuaigaogao") #创建对象
f.talk()#输出
hello shuaigaogao
View Code
总结:类 是由 type 类 实例化产生的
值得注意的是,新式类的写法,在继承父类那边,你继承一个父类后面就要加一个逗号,加逗号,它就把它当做一个元组,不加逗号,就是一个值了