---恢复内容开始---

一、元类的介绍
元类:在python里,一切皆对象。所有自定义的类本身也是元类的对象,即所有自定义的类本质上也是由元类实例化出来的。 class关键字创建自定义类的底层的工作原理(分为四步)
1、先拿到类名
2、再拿到类的基类们 (object,)
3、接着拿到类的名称空间
4、调用元类实例化得到自定义的类 通过class关键字创建一个类 class text:
def __init__(self,name,age):
self.name=name
self.age=age text1=text('jun',18)
print(type(text)) #<class 'type'> 不依赖class自定义一个类:
#1、拿到类名
class_name='text'
#2、拿到类的基类
class_bases=(object,)
#3、拿到类的名称空间
class_dic={} 补充exec的用法:
class_body='''
class text:
def __init__(self,name,age):
self.name=name
self.age=age
'''
exec(class_body,{},class_dic) class_body是局部变量,{}是全局变量 class_dic是名称空间
print(class_dic) # {'text': <class 'text'>} #4、调用type得到自定义的类
temp=type(class_name,class_bases,class_dic)
print(temp) #<class '__main__.text'>
二、自定义元类埃控制类的产生

类的产生:
1、文档必须使用驼峰体
2、类名中必须有文档注释,且文档注释不能为空
#上述为默契,也可以通过代码来达到这些要求 class Mymeta(type):#但凡继承type的类才能称为自定义的元类,否则就只是一个普通的类 def __init__(self,class_name,class_bases,class_dic):
if class_name.islower():
raise TypeError('类名必须使用驼峰体') doc = class_dic.get('__doc__')
if doc is None or len(doc) == 0 or len(doc.strip('\n ')) == 0:
raise TypeError('类体中必须有文档注释,且文档注释不能为空') print(self) #<class '__main__.Oldboy'>
print(class_name) #Oldboy
print(class_bases) #(<class 'object'>,)
print(class_dic) #{'__module__': '__main__', '__qualname__': 'Oldboy', '__init__': <function oldboy.__init__ at 0x00000000021A1730>} class Oldboy(object,metaclass=Mymeta): #oldboy=Mymeta('oldboy',(object,),{})
'''
必须存在文档注释
''' def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex print(Oldboy) #<class '__main__.Oldboy'>

  

三、自定义元类控制类的调用过程

class Mymeta(type):

    pass

class text(object):
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex def __call__(self, *args, **kwargs):
print(self)
print(args)
print(kwargs) temp=text('jun',18,'male') temp(1,2,a=1,b=2) #==__call__(temp,(1,2),{'a':1,'b':2})
#对象的调用 #对象之所以可以调用,是因为对象的类中有一个函数 __call__
#推导:如果一切皆对象,那么text也是一个对象,该对象之所以可以调用,
#是因为该对象的类中也定义了__call__ class Mymeta(type):
def __call__(self, *args, **kwargs): #此处的self=text这个类
# 1、先产生一个空对象
obj=self.__new__(self) #obj是text这个类的对象
 # 2、执行__init__方法,完成对象的初始化属性操作
self.__init__(obj,*args,**kwargs)
print(obj.__dict__) #{'name': 'jun', 'age': 18, 'sex': 'male'} 查找对象的字典
obj.__dict__={('_%s__%s'%(self.__name__,k)):v for k,v in obj.__dict__.items() }
#这一步可以做到私有化属性
print(obj.__dict__) #{'_text__name': 'jun', '_text__age': 18, '_text__sex': 'male'} # 3、返回初始化好的那个对象
return obj class text(object,metaclass=Mymeta):
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex temp=text('jun',18,'male') #会触发元类中的__call__函数
print(temp) #<__main__.text object at 0x0000000001DD9208>
#实例化
#1、先产生一个空对象
#2、执行__init__方法,完成对象的初始化属性操作
#3、返回初始化好的那个对象

补充:exec,eval
# eval内置函数的使用场景:
# 1.执行字符串会得到相应的执行结果
# 2.一般用于类型转化,得到dict、list、tuple等 dic_str = "{'a': 1, 'b': 2, 'c': 3}"
res = (eval('dic_str')) # 得到原先的结果
res1 = (eval(dic_str)) # 得到字符串里面的类型
print(type(res), type(res1)) # <class 'str'> <class 'dict'> list_str = "[1, 2, 3, 4, 5]"
print(list_str, type(list_str)) # [1, 2, 3, 4, 5] <class 'str'>
print(type(eval(list_str))) # <class 'list'> with open('2.txt', 'r', encoding='utf-8') as rf:
data_str = rf.read()
print(data_str, type(data_str)) # [1, 2, 3, 4, 5] <class 'str'> import json # 文件里字典里的key的引号必须为双引号 res = json.loads(data_str) # 字符串转化为其他格式
print(res, type(res)) # [1, 2, 3, 4, 5] <class 'list'> data_str = "{'a': 1, 'b': 2, 'c': 3}" # 可以不考虑引号的种类,直接转换
res = eval(data_str)
print(res, type(res)) # {'a': 1, 'b': 2, 'c': 3} <class 'dict'> # exec应用场景
# 1.执行字符串没有执行结果(没有返回值)
# 2.将执行的字符串中产生的名字形成对应的局部名称空间 s = '''
my_a = 10
my_b = 20
def __init__(self):
pass
@classmethod
def print_msg(msg):
print(msg)
'''
l_dic = {}
exec(s, {}, l_dic) #s是局部变量,{}是全局变量,l_dic名称空间
print(l_dic)
print(l_dic.items()) #{'name': 'Bob', 'age': 20}

  

day 29 元类的更多相关文章

  1. 29 内置方法 eval | exec 元类 单例

    eval与exec内置方法 将字符串作为执行目标,得到响应结果 eval常用作类型转换:该函数执行完有返回值 exec拥有执行更复杂的字符串:可以形成名称空间 eval内置函数的使用场景:   1.执 ...

  2. Python 29 异常处理, 元类

    所学内容 异常处理(常用) AttributeError ··························  试图访问一个对象没有的树形,比如foo.x,但是foo没有属性xIOError ··· ...

  3. Python中的元类和__metaclass__

    1.什么是元类 元类让你来定义某些类是如何被创建的,从根本上说,赋予你如何创建类的控制权.可以把元类想成是一个类中类,或是一个类,它的实例是其它的类.当某个类调用type()函数时,你就会看到它到底是 ...

  4. 【python进阶】详解元类及其应用2

    前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使⽤type创建带有 ...

  5. Python进阶开发之元类编程

    系列文章 √第一章 元类编程,已完成 ; 本文目录 类是如何产生的如何使用type创建类理解什么是元类使用元类的意义元类实战:ORM . 类是如何产生的 类是如何产生?这个问题肯定很傻.实则不然,很多 ...

  6. 神级程序员通过两句话带你完全掌握Python最难知识点——元类!

    千万不要被所谓"元类是99%的python程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...

  7. iOS中类、元类、isa详解

    类相信大家都知道是什么,如果看过runtime的源码或者看过相关的文章对isa肯定也不陌生,不过元类(meta class)大家可能就比较陌生了.不过大家也不要担心,我会细细道来,让大家明白它到底是个 ...

  8. day 26 元类

    一.isinstance issubclass class Person: passclass Student(Person): passstu1=Student()#判断是不是实例print(isi ...

  9. python概念-其实只要简单了解一下,但是却讲了将近两个小时的知识点:元类

    说实话,我真心不太想总结这个东西,算了,炒一下egon的吧 1 引子 1 class Foo: 2 pass 3 4 f1=Foo() #f1是通过Foo类实例化的对象 python中一切皆是对象,类 ...

随机推荐

  1. webpack学习笔记 (一)

    一.安装nodejs: 点击打开nodejs官方站点: 点击下图框住的按钮,下周nodejs安装包: 安装下载好的安装包. 安装完毕之后,在cmd中输入node -v查看是否已经安装成功  如果有版本 ...

  2. Python中怎么读写文件

    python中对文件的操作大概分为三步:打开文件.操作文件(读.写.追加写入).关闭文件. 1.无论对文件做哪种操作,操作前首先要保证文件被打开了,即需要一个打开的操作. 例:open(XXX.txt ...

  3. HttpUrlConnection流传输问题(正确传输包含中文的JSON字符串)

    目前在写一个功能,主要是使用 HttpURLConnection 发送http请求调用外部接口.本来一切正常的,可是在发送post请求上传数据给服务端时,服务端返回错误信息:获取的JSON请求是乱码的 ...

  4. nmap工具简介

    nmap参数介绍: -sL:简单列表扫描 -sn:扫描主机,但是不进行端口扫描 -sS:TCP SYN扫描[半开放扫描,扫描速度高且隐蔽性好] -p |-F:扫描端口列表与扫描次序,常用的扫描方式[- ...

  5. tomcat发布项目如何通过域名直接访问

    首先在服务器中找到tomcat安装后的文件夹,进入到conf目录下,找到server.xml文件 打开并修改,修改如下: 第一步:修改port,该值默认为8080,将其修改为80 第二步:修改defa ...

  6. C# 结构与类的区别

    一.定义方式 定义结构: struct PointStruct //默认的访问权限是 public { public int X { get; set; } public int Y { get; s ...

  7. 学号 20175212童皓桢 《Java程序设计》第8周学习总结

    学号 20175212童皓桢 <Java程序设计>第8周学习总结 教材学习内容总结 泛型 class People<E> 其中People是泛型类的名称,E是其中的泛型,也就是 ...

  8. SpringBoot 下 mybatis 的缓存

    背景: 说起 mybatis,作为 Java 程序员应该是无人不知,它是常用的数据库访问框架.与 Spring 和 Struts 组成了 Java Web 开发的三剑客--- SSM.当然随着 Spr ...

  9. CPU、GPU、CUDA、cuDNN

    CPU擅长逻辑处理控制,GPU适合高强度的并行计算任务,为什么会存在这种差别?今天搜集了些相关资料,摘抄总结如下. 一.什么是GPU GPU这个概念是由Nvidia公司于1999年提出的.GPU是显卡 ...

  10. 原生js手动轮播图

    手动轮播图,为轮播图中的一种,轮播图主要有无缝轮播,手动轮播,延迟轮播,切换轮播等等... 轮播图主要用于展现图片,新出商品,词条,又能美观网页.給网页中增加动态效果. 手动轮播,是小编认为最简单的一 ...