python基础之反射内置方法元类

补充内置函数

isinstance(obj,Foo)   # 判断obj是不是foo的实例

issubclass()      # 判断一个类是不是另一个类的子类

反射

什么是反射?

通过字符串来操作类或者对象的属性

怎么用?

hasattr(adj,’xxx’) 判断adj有没有’xxx’属性

getattr(adj,’xxx’,None) adj有’xxx’就返回adj.xxx,没有则返回None,若不指定第三个                                 参数,没有则会报错

setattr(adj,’age’,18) adj.age = 18

delattr(adj,’age’) def adj.age

内置方法

def __str__(self):在对象被打印时,自动触发,应该在该方法内采集与对象有关的信息并return,当print(adj)是会打印__str__(self)中的return值

def __del__(self) 析构方法,对象被删之前自动触发

元类

什么是元类?

python中一切皆对象,用class定义的类本身也是一个对象,负责产生该类对象的类称为元类

为何用元类?

元类可以负责产生类,进而控制类的产生还可以控制对象的产生

如何用元类?

①储备知识:

exec()

参数一:字符串形式的命令

参数二:全局作用域(字典形式),如果不指定,默认为globals()

参数三:局部作用域(字典形式),如果不指定,默认为locals()

可以把exec命令的执行当成是一个函数的执行,会将执行期间产生的名字存放于局部名称空间中

创建类的三个要素:类名,父类,类的名称空间
#类名
class_name='Chinese'
#类的父类
class_bases=(object,)
#类的名称空间
class_dic = {}
#类体
class_body="""
country='China'
def __init__(self,name,age):
self.name=name
self.age=age
def talk(self):
print('%s is talking' %self.name)
"""
exec(class_body,{},class_dic)
People = type(class_name,class_bases,class_dic) # 实例化类

class运行原理:

1.拿到一个字符串形式的类名

2.拿到类的基类们

3.执行类体代码,拿到类的名称空间

4.调用type()再赋值给变量名

应用:自定义元类控制类的产生过程,其实就是调用元类的过程

#如果说People=type(类名,类的父类们,类的名称空间),那么我们定义元类如下,来控制类的创建
class Mymeta(type): # 继承默认元类的一堆属性
def __init__(self, class_name, class_bases, class_dic):
if '__doc__' not in class_dic or not class_dic.get('__doc__').strip():
raise TypeError('必须为类指定文档注释') if not class_name.istitle():
raise TypeError('类名首字母必须大写') super(Mymeta, self).__init__(class_name, class_bases, class_dic) class People(object, metaclass=Mymeta):
country = 'China' def __init__(self, name, age):
self.name = name
self.age = age def talk(self):
print('%s is talking' % self.name) #自定义元类,控制类的调用(即实例化)的过程
class Mymeta(type): #继承默认元类的一堆属性
def __init__(self,class_name,class_bases,class_dic):
if not class_name.istitle():
raise TypeError('类名首字母必须大写') super(Mymeta,self).__init__(class_name,class_bases,class_dic) def __call__(self, *args, **kwargs):
#self=People
print(self,args,kwargs) #<class '__main__.People'> ('egon', 18) {} #1、实例化People,产生空对象obj
obj=object.__new__(self) #2、调用People下的函数__init__,初始化obj
self.__init__(obj,*args,**kwargs) #3、返回初始化好了的obj
return obj class People(object,metaclass=Mymeta):
country='China' def __init__(self,name,age):
self.name=name
self.age=age def talk(self):
print('%s is talking' %self.name) obj=People('egon',18)
print(obj.__dict__) #{'name': 'egon', 'age': 18}
上一篇:July 12th, 2018. Thursday, Week 28th.


下一篇:HDU2243 考研路茫茫――单词情结