反射
class People:
def __init__(self,name,age):
self.name=name
self.age=age
def say(self):
print('<%s:%s>' %(self.name,self.age))
obj=People('辣白菜同学',18)
print(dir(obj))
print(obj.__dict__[dir(obj)[-2]])
1、hasattr()
print(hasattr(obj,'name'))
print(hasattr(obj,'x'))
2、getattr()
print(getattr(obj,'name'))
3、setattr()
setattr(obj,'name','EGON')
print(obj.name)
4、delattr()
delattr(obj,'name')
print(obj.__dict__)
res1=getattr(obj,'say')
res2=getattr(People,'say')
print(res1)
print(res2)
obj=10
if hasattr(obj,'x'):
print(getattr(10,'x'))
else:
pass
print(getattr(obj,'x',None))
if hasattr(obj,'x'):
setattr(obj,'x',111111111)
else:
pass
class Ftp:
def put(self):
print('正在执行上传功能')
def get(self):
print('正在执行下载功能')
def interactive(self):
method=input(">>>: ").strip()
if hasattr(self,method):
getattr(self,method)()
else:
print('输入的指令不存在')
obj=Ftp()
obj.interactive()
内置方法
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "<%s:%s>" % (self.name, self.age)
obj = People('辣白菜同学', 18)
print(obj)
class People:
def __init__(self, name, age):
self.name = name
self.age = age
self.x = open('a.txt', mode='w')
def __del__(self):
self.x.close()
obj = People('辣白菜同学', 18)
print('============>')
元类
一:引入:
一切都源自于一句话:一切皆为对象
二:什么是元类?
元类就是用来实例化产生类的类
关系:元类---实例化--- -> 类(People)- --实例化--- -> 对象(obj)
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print('%s:%s' % (self.name, self.name))
print(People.__dict__)
如何得到对象
obj = 调用类()
obj = People('egon', 18)
print(type(obj))
如果说类也是对象
People = 调用类(。。。)
查看内置的元类:
1、type是内置的元类
2、我们用class关键字定义的所有的类以及内置的类都是由元类type实例化产生
print(type(People))
print(type(int))
三:class关键字创造类People的步骤
类有三大特征:
class_name = "People"
class_bases = (object,)
class_dic = {}
class_body = """
def __init__(self,name,age):
self.name=name
self.age=age
def say(self):
print('%s:%s' %(self.name,self.name))
"""
exec(class_body, {}, class_dic)
People = type(class_name, class_bases, class_dic)
四:如何自定义元类来控制类的产生
class Mymeta(type):
def __init__(self, x, y, z):
print('run22222222222....')
print(self)
def __new__(cls, *args, **kwargs):
print('run1111111111.....')
return type.__new__(cls, *args, **kwargs)
class People(metaclass=Mymeta):
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print('%s:%s' % (self.name, self.name))
五:__call__
class Foo:
def __init__(self, x, y):
self.x = x
self.y = y
def __call__(self, *args, **kwargs):
print('===>', args, kwargs)
return 123
obj = Foo(111, 222)
res = obj(1, 2, 3, a=4, b=5, c=6)
print(res)
应用:如果想让一个对象可以加括号调用,需要在该对象的类中添加一个方法__call__
总结:
对象() -> 类内的__call__
类() -> 自定义元类内的__call__
自定义元类() -> 内置元类__call__
六:自定义元类控制类的调用 =》类的对象的产生
class Mymeta(type):
def __call__(self, *args, **kwargs):
people_obj = self.__new__(self)
self.__init__(people_obj, *args, **kwargs)
people_obj.__dict__['xxxxx'] = 11111
return people_obj
类的产生
People = Mymeta() =》type.__call__ = >干了3件事
1、type.__call__函数内会先调用Mymeta内的__new__
2、type.__call__函数内会调用Mymeta内的__init__
3、type.__call__函数内会返回一个初始化好的对象
class People(metaclass=Mymeta):
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print('%s:%s' % (self.name, self.name))
def __new__(cls, *args, **kwargs):
return object.__new__(cls)
obj1 = People('egon', 18)
obj2 = People('egon', 18)
print(obj1.__dict__)
print(obj2.__dict__)
属性查找
class Mymeta(type):
n=444
def __call__(self, *args, **kwargs):
obj=self.__new__(self)
print(self.__new__ is object.__new__)
self.__init__(obj,*args,**kwargs)
return obj
class Bar(object):
pass
class Foo(Bar):
pass
class StanfordTeacher(Foo,metaclass=Mymeta):
def __init__(self,name,age):
self.name=name
self.age=age
obj=StanfordTeacher('lili',18)
print(obj.__dict__)