python元类深入理解
1.python 中的类
在python中,类也是一个对象,只不过这个对象拥有生成实例的能力,我们一般使用class XXX来定义一个类,在python解释器执行到这个地方的时候会自动创建出这个对象,python也为我们提供了手动创建类的方法,type()。type()这个方法对我们来说并不陌生,我们所熟知的用法是:class = type(instance),当传入一个参数时,type()返回这个参数的类。而今天我们要用到的是type的另一个功能。type("classname",(object,),{"name":"jiao"})。当给type传入三个参数时,就是一个手动创建类的方式。
class A():def __init__(self,name):self.name = nameprint("创建了一个实例")a = type("a",(A,),{"name":"jiao"}) print(a) #<class '__main__.a'> print(a.name) #jiao print(a("jiang")) #创建了一个实例 #<__main__.a object at 0x00000280A973AA58>
type接收三个参数分别是:
classname: 要创建的class 的名称
object:要创建类的父类所组成的元组
sttr_dict: 要创建类的属性
type返回一个class,我们接收并赋值到一个变量上,现在这个变量就指向我们所创建的类,我们可以通过这个变量来使用类。
2.python 中的type
在python 中,几乎所有的东西都是对象,这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来——type
3.__metaclass__属性
python在创建类时,会按照如下的流程进行:
Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类对象(我说的是类对象,请紧跟我的思路)。如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。
那么在__metaclass__中放置什么样的代码可以创建类呢?type,或者任何使用到type或者子类化type的东东都可以。
4.自定义元类
class UpperAttrMetaClass(type):def __new__(cls,class_name,class_parents,class_attr, *args, **kwargs):print("__new__")class_attr['name'] = "jiao"return type.__new__(cls,class_name,class_parents,class_attr)def __init__(self,*args,**kwargs):print("__init__")super().__init__(*args, **kwargs)self.__cache = {}def __call__(self, *args, **kwargs):print("__call__")if args in self.__cache:return self.__cache[args]else:obj = super().__call__(*args)self.__cache[args] = objreturn objclass A(metaclass=UpperAttrMetaClass):def __init__(self,name):self.name = nameprint("a.__init__")
5.类的创建流程
1.元类的__new__(),返回创建好的类。当我们想要改变创建方式的时候就要重写这个方法。
2.元类的__init__(),初始化一些类的属性
6.实例创建流程
1.元类的__call__(),创建一个实例时,首先调用这个方法,返回创建好的实例,所以我们可以通过改写这个方法来改变实例创建过程,比如实现单例模式
2.类的__init__(),初始化实例属性
7.元类的应用
1.单例模式
class Singleton(type):def __init__(cls,*args,**kwargs):cls.__instance = Nonesuper().__init__(*args,**kwargs)def __call__(cls, *args, **kwargs):if cls.__instance is None:cls.__instance = super().__call__(*args,**kwargs)return cls.__instanceelse:return cls.__instanceclass Spam(metaclass=Singleton):def __init__(self):print("Creating Spam")
2.缓存模式
import weakrefclass Cached(type):def __init__(cls,*args,**kwargs):super().__init__(*args,**kwargs)cls.__cache = weakref.WeakValueDictionary()def __call__(cls, *args, **kwargs):if args in cls.__cache:return cls.__cache[args]else:obj = super().__call__(*args)cls.__cache[args] = objreturn objclass Spams(metaclass=Cached):def __init__(self,name):print("Creating Spam({!r})".format(name))self.name = name
3.获取属性的定义顺序
能过获取到属性的定义顺序,我们就可以通过简单的方法实现属性到数据的映射,可以更加简单的将类中的属性数据化。
from collections import OrderedDictclass Typed:_excepted_type = type(None)def __init__(self,name=None):self._name = namedef __set__(self, instance, value):if not isinstance(value,self._excepted_type):raise TypeError("Excepted"+str(self._excepted_type))instance.__dict__[self._name] = valueclass Integer(Typed):_excepted_type = intclass Float(Typed):_excepted_type = floatclass String(Typed):_excepted_type = strclass OrderedMeta(type):def __new__(cls, clsname,bases,clsdict):d = dict(clsdict)order = []for name,value in clsdict.items():if isinstance(value,Typed):value._name = nameorder.append(name)d['_order'] = orderreturn type.__new__(cls,clsname,bases,d)@classmethoddef __prepare__(metacls, name, bases):return OrderedDict()#注:__prepare__该方法会在类定义一开始的时候调用,调用时以类名和基类名称作为参数,它必须返回一个映射对象,供处理类定义体时调用#eg. class Structure(metaclass=OrderedMeta):def as_csv(self):return ','.join(str(getattr(self,name)) for name in self._order)class Stock(metaclass=OrderedMeta):name = String()shares = Integer()price = Float()def __init__(self,name,shares,price):self.name = nameself.shares = sharesself.price = prices = Stock("haha",23,23.3) print(s.name) s = Stock(34,23,34) # print(s.as_csv())
8.小结
元类主要就是在类和实例创建的时候发挥作用,来实现一些功能。
转载于:https://www.cnblogs.com/jiaojianglong/p/11260944.html
python元类深入理解相关推荐
- Python中type的使用和元类的理解
"元类就是深度的魔法,99%的用户应该根本不必为此操心.如果你想搞清楚究竟是否需要用到元类,那么你就不需要它.那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需 ...
- python 元类工厂模式_Python进阶丨如何创建你的第一个Python元类?
摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...
- 如何创建你的第一个Python元类?
Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一.通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类.本文介绍 ...
- Python进阶丨如何创建你的第一个Python元类?
摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...
- python元类_Python元类
python元类 Welcome to today's tutorial on python metaclass. We all know that python is an object orien ...
- python元类_Python基础:元类
一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯面向对象 的.与那些仅在语法层面声称纯OO的编程语言(如Java)相比,Python的这种纯粹性更加深入骨髓. 在Python的世界 ...
- Python元类详解
文章目录 Python元类详解 Python谜团 元类的本质 调用一个类时发生了什么 再探元类 自定义元类 彩蛋:跳过python解释器 Python元类详解 元类比99%的用户所担心的魔法要更深,如 ...
- python中的元类_理解python中的元类
一,理解类也是对象 在python中类同样也是一种对象,只要使用关键字class,Python解释器在执行的时候就会创建一个对象,这个对象(类)自身拥有创建对象(类实例)的能力,这就是为什么他是一个类 ...
- 深入理解Python元类(原创)
同样效果的代码: def __init__(cls,cls_name,cls_bases,cls_dict):type.__init__(cls,cls_name,cls_bases,cls_dict ...
最新文章
- C语音中声明与定义的区别
- skylake服务器处理器M系列,行业——华为三大v5机架式服务器改用Skylake处理器
- caffe转caffe2
- SSL证书安装指南 - Winodws 2003 Server IIS 6.0
- 合并财务报表无条件抵销分录
- 介绍一下XMLHttpRequest对象,他有哪些常用方法和属性
- datagrid vue_类似 easyui 中 datagrid 使用习惯的 element-ui 数据表格组件(el-datagrid)...
- W ndoWs文件夹窗口,如何在本地网络中访问-Synology-NAS-上的文件-(Wndows).pdf
- 【C语言】str类与men库函数的实现(如:strcpy,strcmp,strstr,strcat,memmove,memcpy)
- html如何太假icon图标,CSS3 icon font完全指南(CSS3 font 会取代icon图标)
- UI设计干货素材|聊天APP界面,临摹学习进步快
- apso matlab,APSO算法指导
- idea ssm框架搭建详细步骤_搭建一套纯净版的SSM框架,随时CV使用它不香吗?
- 攻击者接管账户,攻陷周下载量超700万次的JavaScript 流行库 ua-parser-js
- Learn ZYNQ (7)
- GPS坐标系转换工具类
- 解决......lib/include/THC/THCGeneral.h:12:18: fatal error: cuda.h: No such file or directory报错问题
- 【踩坑笔记】java使用poi导出word文档换行
- (转载)从鼠尾草凋谢看中国花花世界的阴影(附EmilMatthew的评论)
- String转字节数组