元类

在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. YTU 2573: 连续奇数和

    2573: 连续奇数和 时间限制: 1 Sec  内存限制: 128 MB 提交: 63  解决: 37 题目描述 小明看到一本书上写着:任何数字的立方都可以表示为连续奇数的和. 比如: 2^3 = ...

  2. 【转】Java 并发编程:核心理论

    并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能.它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰.思维缜密,这样才能写出高效.安全.可靠的多线程并发程序.本系 ...

  3. NABCD项目需求报告

    项目:记账小账本 N:need 需求 根据我们的调查,很多人虽然知道记账有很多的好处,但是因为种种的原因,我们都没能养成记账的好习惯,所以我们所做的记账小软件,说到底是一个行为养成类的软件,而这类软件 ...

  4. 常用的 Nand Flash 指令如下:

    指令 功能 nand info 显示可使用的 Nand Flash nand device [dev] 显示或设定当前使用的 Nand Flash nand read  addr off  size ...

  5. sql 指删除表,改表名,改字段名

    删除表: DECLARE @Table NVARCHAR(30) DECLARE tmpCur CURSOR FOR SELECT name FROM sys.objects WHERE TYPE=' ...

  6. ubuntu mysql5.6二进制安装

    200 ? "200px" : this.width)!important;} --> 介绍 以前一直使用centos今天需要对一台ubantu的系统安装mysql,虽然它也 ...

  7. 0 Java实现 一篇文章说尽设计模式之六大原则

    我们知道,设计模式很有用,学好设计模式不但能让你写出更简洁,优雅的代码,还能使得代码的结构更清晰,也更有利于扩展 当然设计模式也不是万能的,一成不变的.设计模式只是前人总结出来的一种经验,一种特定问题 ...

  8. (3)css文本样式

    本篇学习资料主要讲解: 如何用css 的样式定义方法来介绍文字的使用. 第(1)节:用css设置文本样式.                       一.弄懂文本文字的制作.利用css的样式定义版面 ...

  9. notepad++无法设置成默认打开方式

    安装软件自动保存到默认的目录下(c盘下)

  10. jQuery查找

    导航查找方法: 向下查找兄弟标签: $().next() $().nextAll() 向上查找兄弟标签: 可以查找所有兄弟标签: 查找子标签 查找父级标签: $().parent() $().pare ...