元类

在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. BZOJ_3881_[Coci2015]Divljak_AC自动机+dfs序+树状数组

    BZOJ_3881_[Coci2015]Divljak_AC自动机+dfs序+树状数组 Description Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是 ...

  2. 洛谷 P1072 Hankson 的趣味题 —— 质因数分解

    题目:https://www.luogu.org/problemnew/show/P1072 满足条件的数 x 一定是 a1 的倍数,b1 的因数,a0/a1 与 x/a1 互质,b1/b0 与 b1 ...

  3. 获取http请求的响应状态

    import urllib.request url="http://www.baidu.com" #返回一个对象 response=urllib.request.urlopen(u ...

  4. c++性能测试工具:google benchmark入门(二)

    上一篇中我们初步体验了google benchmark的使用,在本文中我们将更进一步深入了解google benchmark的常用方法. 本文索引 向测试用例传递参数 简化多个类似测试用例的生成 使用 ...

  5. bzoj 2132 圈地计划【最小割+dinic】

    对于网格图,尤其是这种要求相邻各自不同的,考虑黑白染色 对于这张染色后图来说: 对于每个黑格: 表示初始时选择商业区: s点向它连商业区收益的流量,它向t点连工业区收益的流量: 割断S侧的边说明反悔, ...

  6. 原生JavaScript实战之搜索框筛选功能

    成品图如下所示: 先搭建HTML结构: <div class="wrapper"> <div class="sWrapper"> < ...

  7. [POI2008]海报PLA

    Description N个矩形,排成一排. 现在希望用尽量少的矩形海报Cover住它们. Input 第一行给出数字N,代表有N个矩形.N在[1,250000] 下面N行,每行给出矩形的长与宽.其值 ...

  8. C#中的list的System.Predicate<in T>和System.Comparison<in T>的应用

    public class Data { ; ; ; ; public Data() { count++; ma = count; } } //一句话删除满足要求的集合 Asm.RemoveAll((D ...

  9. log4js日志配置问题

    http://blog.csdn.net/cdnight/article/details/50857268 在做项目中,我们的node日志采用的是log4js框架,使用文件方式存储,但在后面的需求中增 ...

  10. mysql 中 时间函数 now() current_timestamp() 和 sysdate() 比较

    转载请注明出处 https://www.cnblogs.com/majianming/p/9647786.html 在mysql中有三个时间函数用来获取当前的时间,分别是now().current_t ...