day24-1 元类
元类
在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 元类的更多相关文章
- python之元编程(元类实例)
本实例是元类实例,功能是记录该的子类的类名,并以树状结构展示子类的类名. RegisterClasses继承自type,提供的功能是在__init__接口,为类创建了childrens的集合,并类名保 ...
- python 元类
转载自 http://blog.jobbole.com/21351/ 类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大 ...
- Python语言特性之2:元类
问题:Python中的元类(metaclasses)是什么?一般使用它干什么? 原地址:http://stackoverflow.com/questions/100003/what-is-a-meta ...
- python基础——使用元类
python基础——使用元类 type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello. ...
- [python]python元类
这两天在看Django框架,里面的filter实现原理搞不明白,最后发现跟python的元类有关系. 原文:http://stackoverflow.com/questions/100003/what ...
- Python基础:元类
一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...
- Python中的元类和__metaclass__
1.什么是元类 元类让你来定义某些类是如何被创建的,从根本上说,赋予你如何创建类的控制权.可以把元类想成是一个类中类,或是一个类,它的实例是其它的类.当某个类调用type()函数时,你就会看到它到底是 ...
- 深刻理解Python中的元类metaclass(转)
本文由 伯乐在线 - bigship 翻译 英文出处:stackoverflow 译文:http://blog.jobbole.com/21351/ 译注:这是一篇在Stack overflow上很热 ...
- 元类metaClass
metaClass 实现动态改变对象的能力,这点特别像python(metaClass),Python中类(不是元类)的概念借鉴于Smalltalk groovy demo: class Person ...
- 深刻理解Python中的元类(metaclass)
译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...
随机推荐
- Spring Cloud Sleuth 中id的使用
Spring Cloud Sleuth采用的是Google的开源项目Dapper的专业术语. Span:基本工作单元,发送一个远程调度任务 就会产生一个Span,Span是一个64位ID唯一标识的,T ...
- jquery中一些容易忽略的方法
jquery.ajaxPrefilter:([dataTypes],handle(options,originalOptions,jqXHR)):在发送请求之前和执行$.ajax之前操作options ...
- 函数,#include <>和#include " "区别
l 4..函数定义到使用分三步:1.声明.2.定义函数.3.调用函数. 2.函数的定义格式:返回值 函数名(形参列表){ 函数体; return } 命名规则:1.只能由字母.数字.下划线或者美元符号 ...
- Spring Ioc容器核心类继承图
Spring IOC容器其实就是BeanFactory的实例,Spring中BeanFactory的类关系结构如下图: 从上图可以看出Beanfactory作为根接口又细化出三个二级接口,最后又有Co ...
- bzoj 4571 美味 —— 主席树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4571 区间找异或值最大,还带加法,可以用主席树: 可以按位考虑,然后通过加上之前已经有的答案 ...
- zoj 3471(状态压缩DP,类似于点集配对)
Most Powerful Time Limit: 2 Seconds Memory Limit: 65536 KB Recently, researchers on Mars have d ...
- logback 使用详解 (转)
详细整理了logback常用配置, 不是官网手册的翻译版,而是使用总结,旨在更快更透彻的理解其配置 logback 常用配置详解(序)logback 简介 logback 常用配置详解(一)<c ...
- Luogu P2921 在农场万圣节 【tarjan in 有向图】 By cellur925
题目传送门 上来就想到既直接又简单的暴力方法,顺着每个房间的下一个走下去就好了,但是没想到最坏情况会达到1e5,100000的数据铁定超时. #include<cstdio> #inclu ...
- 【转】Hive安装及使用攻略
Posted: Jul 16, 2013 Tags: HadoophiveHiveQLsql分区表 Comments: 18 Comments Hive安装及使用攻略 让Hadoop跑在云端系列文章, ...
- QT5每日一学(五)QT布局管理器
Qt中的布局管理器主要包括 QBoxLayout基本布局管理器 QGridLayout栅格布局管理器 QFormLayout窗体布局管理器 而基本布局管理器又分为QHBoxLayout水平布局管理器和 ...