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元类深入理解相关推荐

  1. Python中type的使用和元类的理解

            "元类就是深度的魔法,99%的用户应该根本不必为此操心.如果你想搞清楚究竟是否需要用到元类,那么你就不需要它.那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需 ...

  2. python 元类工厂模式_Python进阶丨如何创建你的第一个Python元类?

    摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...

  3. 如何创建你的第一个Python元类?

    Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一.通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类.本文介绍 ...

  4. Python进阶丨如何创建你的第一个Python元类?

    摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...

  5. python元类_Python元类

    python元类 Welcome to today's tutorial on python metaclass. We all know that python is an object orien ...

  6. python元类_Python基础:元类

    一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯面向对象 的.与那些仅在语法层面声称纯OO的编程语言(如Java)相比,Python的这种纯粹性更加深入骨髓. 在Python的世界 ...

  7. Python元类详解

    文章目录 Python元类详解 Python谜团 元类的本质 调用一个类时发生了什么 再探元类 自定义元类 彩蛋:跳过python解释器 Python元类详解 元类比99%的用户所担心的魔法要更深,如 ...

  8. python中的元类_理解python中的元类

    一,理解类也是对象 在python中类同样也是一种对象,只要使用关键字class,Python解释器在执行的时候就会创建一个对象,这个对象(类)自身拥有创建对象(类实例)的能力,这就是为什么他是一个类 ...

  9. 深入理解Python元类(原创)

    同样效果的代码: def __init__(cls,cls_name,cls_bases,cls_dict):type.__init__(cls,cls_name,cls_bases,cls_dict ...

最新文章

  1. C语音中声明与定义的区别
  2. skylake服务器处理器M系列,行业——华为三大v5机架式服务器改用Skylake处理器
  3. caffe转caffe2
  4. SSL证书安装指南 - Winodws 2003 Server IIS 6.0
  5. 合并财务报表无条件抵销分录
  6. 介绍一下XMLHttpRequest对象,他有哪些常用方法和属性
  7. datagrid vue_类似 easyui 中 datagrid 使用习惯的 element-ui 数据表格组件(el-datagrid)...
  8. W ndoWs文件夹窗口,如何在本地网络中访问-Synology-NAS-上的文件-(Wndows).pdf
  9. 【C语言】str类与men库函数的实现(如:strcpy,strcmp,strstr,strcat,memmove,memcpy)
  10. html如何太假icon图标,CSS3 icon font完全指南(CSS3 font 会取代icon图标)
  11. UI设计干货素材|聊天APP界面,临摹学习进步快
  12. apso matlab,APSO算法指导
  13. idea ssm框架搭建详细步骤_搭建一套纯净版的SSM框架,随时CV使用它不香吗?
  14. 攻击者接管账户,攻陷周下载量超700万次的JavaScript 流行库 ua-parser-js
  15. Learn ZYNQ (7)
  16. GPS坐标系转换工具类
  17. 解决......lib/include/THC/THCGeneral.h:12:18: fatal error: cuda.h: No such file or directory报错问题
  18. 【踩坑笔记】java使用poi导出word文档换行
  19. (转载)从鼠尾草凋谢看中国花花世界的阴影(附EmilMatthew的评论)
  20. String转字节数组

热门文章

  1. dev c++ 调试时候发生软件崩溃解决办法
  2. PyTorch-Adam优化算法原理,公式,应用
  3. ESLint问题记录
  4. LeetCode简单题之复写零
  5. 通俗易懂的Go协程的引入及GMP模型简介
  6. 激光雷达lidar与点云数据
  7. TensorFlow中的语义分割套件
  8. 凭借128核芯片,安培寻求提供可靠的进步
  9. Tensor Core技术解析(上)
  10. AlexeyAB DarkNet YOLOv3框架解析与应用实践(五)