元类

在python中一切皆对象,name我们用class关键字定义的类本身也是一个对象,负责产生该对象的类称之为元类,即元类可以简称为类的类

元类是负责产生类的,所以我们学习元类或者定义元类的目的是:为了控制类的产生过程,还可以控制对象的产生过程

类的组成

class People(object):
x = 1
print('from people')
def __init__(self, name, age):
self.name = name
self.age = age def speak(self):
print('from speak')

在用class关键字定义类时,在定义阶段会执行类体中的代码,创建名称空间,所以类由三部分组成

  • 类名class_name:People
  • 基类class_bases:(object,)
  • 类的名称空间class_dic

内置函数 exec()

将字符串中的代码执行,然后把产生的全局名称丢入到global_space字典中,局部名称丢入到local_space字典中

cmd = """
x = 1
global y
y = 10
def __init__(self, name, age):
self.name = name
self.age = age def speak(self):
print('from speak')
"""
global_space = {}
local_space = {}
exec(cmd,global_space,local_space) # 未声明gloabal的变量全是局部变量
print('local:',local_space)
local: {'x': 1, '__init__': <function __init__ at 0x000002C2319EB158>, 'speak': <function speak at 0x000002C2319EB0D0>}

class关键字创建类原理

用class关键字创建一个类,用的默认的元类type

class_name = 'P'  # 类名
class_bases = (object,) # 基类
cmd = """
x = 1
global y
y = 10
def __init__(self, name, age):
self.name = name
self.age = age def speak(self):
print('from speak')
"""
global_space = {}
local_space = {}
exec(cmd,global_space,local_space)
class_dic = local_space # 类的名称空间 P= type(class_name, class_bases, class_dic)
print(P)
<class '__main__.P'>

自定义元类控制类的创建

  • 控制创建类时必须写说明,没写就抛出异常
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dict):
if not class_dict.get('__doc__'):
raise TypeError('必须写说明')
super(Mymeta, self).__init__(class_name, class_bases, class_dict) class People(object, metaclass=Mymeta):
"""
SJFDSFSD
"""
country = 'Chinese' def __init__(self, name, age):
self.name = name
self.age = age def test(self):
print('from f1')
  • 控制创建类时类名不能全为小写,类名全为小写则抛出异常
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dict):
if class_name.islower():
raise TypeError('类名不能全为小写')
super(Mymeta, self).__init__(class_name, class_bases, class_dict) class People(object, metaclass=Mymeta):
country = 'Chinese' def __init__(self, name, age):
self.name = name
self.age = age def test(self):
print('from f1')

自定义元类控制类实例化

类的实例化就是元类的调用,类实例化原理:

  • 先造出一个空对象
  • 为该空对象初始化独有的属性
  • 返回一个初始化好的对象
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dict):
super(Mymeta, self).__init__(class_name, class_bases, class_dict) # 控制类Foo的调用过程,即控制实例化Foo的过程
def __call__(self, *args, **kwargs): # 造一个空对象obj
obj = object.__new__(self) # 调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__
self.__init__(obj, *args, **kwargs)
return obj class Foo(object, metaclass=Mymeta):
x = 10 def __init__(self, y):
self.y = y f = Foo(1)
print(f.__dict__)
{'y': 1}

自定义元类后对象属性查找顺序

对象本身-->类-->父类-->父类-->object-->type找不到报错

day24-1 元类的更多相关文章

  1. python之元编程(元类实例)

    本实例是元类实例,功能是记录该的子类的类名,并以树状结构展示子类的类名. RegisterClasses继承自type,提供的功能是在__init__接口,为类创建了childrens的集合,并类名保 ...

  2. python 元类

    转载自  http://blog.jobbole.com/21351/ 类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大 ...

  3. Python语言特性之2:元类

    问题:Python中的元类(metaclasses)是什么?一般使用它干什么? 原地址:http://stackoverflow.com/questions/100003/what-is-a-meta ...

  4. python基础——使用元类

    python基础——使用元类 type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello. ...

  5. [python]python元类

    这两天在看Django框架,里面的filter实现原理搞不明白,最后发现跟python的元类有关系. 原文:http://stackoverflow.com/questions/100003/what ...

  6. Python基础:元类

    一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...

  7. Python中的元类和__metaclass__

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

  8. 深刻理解Python中的元类metaclass(转)

    本文由 伯乐在线 - bigship 翻译 英文出处:stackoverflow 译文:http://blog.jobbole.com/21351/ 译注:这是一篇在Stack overflow上很热 ...

  9. 元类metaClass

    metaClass 实现动态改变对象的能力,这点特别像python(metaClass),Python中类(不是元类)的概念借鉴于Smalltalk groovy demo: class Person ...

  10. 深刻理解Python中的元类(metaclass)

    译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...

随机推荐

  1. shell网络管理

    背景知识 联网就是通过网络将主机进行互联并采用不同的规范配置网络上的节点.我们以 TCP/IP 作为网络栈,所有的操作都是基于它进行的.网络是计算机系统中重要的部分.连接在网络上的每个节点都分配了一个 ...

  2. 强大的DataGrid组件[7]_自定义DataGrid——Silverlight学习笔记[15]

    基本知识讲解 1)两种状态 DataGrid的单元格的状态有两类,即编辑状态和非编辑状态. 在实际开发中,如果一个单元格所在的列不设为只读的话(即要求可读写),那么这个单元格就存在这两种状态.按需要, ...

  3. JSP 与 ACTION 之间的跳转

    <script language="javascript">function delconfirm(url){ if(confirm("你确定要删除本条数据吗 ...

  4. bzoj 2962 序列操作 —— 线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2962 维护 sum[i] 表示选 i 个的乘积和,合并两个子树就枚举两边选多少,乘起来即可: ...

  5. python标准输入,标准输出,标准错误

    sys.stdout 与 print 当我们在 Python 中打印对象调用 print obj 时候,事实上是调用了 sys.stdout.write(obj+'\n') print 将你需要的内容 ...

  6. 276D

    贪心 想了一会觉得没什么很好的方法,看了题解 我们枚举每个二进制位,对于l,r如果这位相同就异或到答案里,否则停止,这里肯定是r比l大,也就是r这位是1而l是0,那么我们就让r这位选1,l选0,然后把 ...

  7. mongoDB学习资料整理

    mongoDB入门篇 http://www.imooc.com/view/246

  8. TensorFlow博客翻译——用TensorFlow在云端进行机器学习

    https://github.com/tensorflow/tensorflow 原文地址 Machine Learning in the Cloud, with TensorFlow Wednesd ...

  9. [软件安装]JDK

    一.软件简介1.java开发.java应用的系统基础环境2.软件版本会不同有少许差异,一般是稳定上升 二.安装环境:1.时间:2017年4月5日2.系统:centos7.3 64位(阿里云)3.软件版 ...

  10. bzoj 2115: [Wc2011] Xor【线性基+dfs】

    -老是想到最长路上 其实可以这样:把每个环的xor和都存起来,然后任选一条1到n的路径的xor和ans,答案就是这个ans在环的线性基上跑贪心. 为什么是对的--因为可以重边而且是无相连通的,并且对于 ...