元类

元类(A) ---> 类(B) ---> 实例(C)

对于实例C而言,它是对象,它的类就是类B

对于类B而言,它其实也是对象,那它的类就是元类A

对于元类A而言,它其实也是对象,那它的类就是自己本身

造类

第一阶段

class Foo:
count = 0
def __init__(self,name):
self.name = name
def eat(self):
print("eat")
def run(self):
print("run") # ------------------------------------------ class_name = "Foo" # 类名
class_bases = (object,) # 继承类
class_body = """
count = 0
def __init__(self,name):
self.name = name
def eat(self):
print("eat")
def run(self):
print("run")
"""
class_dict = dict() # dict属性和方法
exec(class_body,{},class_dict) # 将class_bady中的字符串,转化为键值对存储到class_dict中
one = type(class_name,class_bases,class_dict) # 使用type创建类 print(one)
print(Foo)
<class '__main__.Foo'>
<class '__main__.Foo'>

这时,我们发现通过type创建出来一个和Foo相同的类one,但是这里的变量太死板了,我们还需要改变一下

第二阶段

class  Foo(type):
def __init__(self,class_name,class_bases,class_dict):
if not class_dict.get("__doc__"):
raise TypeError("请加上注释")
super().__init__(class_name,class_bases,class_dict) class person(object,metaclass=Foo): def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex def run(self):
print("run") def eat(self):
print("eat") one = person('plf',18,'男')
print(one.name)
print(one.age)
print(one.sex)
Traceback (most recent call last):
File "E:/***/***/***/test1.py", line 15, in <module>
class person(object, metaclass=Foo):
File "E:/***/***/***/test1.py", line 11, in __init__
raise TypeError("请加上注释")
TypeError: 请加上注释

因为我们在Foo类的__init__方法中对创建类的条件做了一些逻辑处理(如果类中没有注释,直接抛异常),解决的办法:第九行加上注释即可

class  Foo(type):
def __init__(self,class_name,class_bases,class_dict):
if not class_dict.get("__doc__"):
raise TypeError("请加上注释")
super().__init__(class_name,class_bases,class_dict) class person(object,metaclass=Foo):
'''我加上注释了'''
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex def run(self):
print("run") def eat(self):
print("eat")

总结:元类创建类,主要__init__方法中增加逻辑

造对象

NAME = 'PLF'
AGE = 18
class Foo(type):
def __init__(self,class_name,class_bases,class_dict):
self.count = 1
super().__init__(class_name,class_bases,class_dict) def __call__(self, *args, **kwargs):
# 造空类
obj = object.__new__(self)
# 造对象
if len(args) == 0 and len(kwargs) == 0:
self.__init__(obj,NAME,AGE)
return obj
self.__init__(obj,*args,**kwargs)
return obj class Person(object,metaclass=Foo):
def __init__(self, name, age):
self.name = name
self.age = age def run(self):
print("run") def eat(self):
print("eat") def __call__(self, *args, **kwargs):
print("调用了")
# return self one = Person('zhangsan',1000)
print('one对象的name:',one.name)
print('one对象的age:',one.age) ori = Person()
print('ori对象的name:',ori.name)
print('ori对象的name:',ori.age)
one对象的name: zhangsan
one对象的age: 1000
ori对象的name: PLF
ori对象的name: 18

总结:通过元类造对象,操作的逻辑可以在__call__方法或者__new__方法中进行

python面向对象之元类的更多相关文章

  1. Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法

    Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...

  2. Python面向对象之元类(metaclass)

    点进来看就完事了铁汁!      

  3. python基础——使用元类

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

  4. Python基础:元类

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

  5. [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式

    使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...

  6. 什么是python中的元类

    所属网站分类: python高级 > 面向对象 作者:goodbody 原文链接: http://www.pythonheidong.com/blog/article/11/ 来源:python ...

  7. Python中的元类(metaclass)

    推荐+收藏:深刻理解Python中的元类(metaclass) 做一些笔记学习学习: 在大多数编程语言中,类就是用来描述如何生成一个对象的代码段,在Python中类也是一个对象,这个(类)对象自身拥有 ...

  8. Python面向对象之接口类(抽象类)

    Python面向对象之接口类(抽象类):就是制定一个规范. 比如定义了一个接口类(抽象类)(他们是不可以进行实例化的,这就是他为什么是制定一个规范的原因). 他的定义是需要abc模块,要变的就是他的方 ...

  9. [Python之路] 元类(引申 单例模式)

    一.类也是对象 当我们定义一个变量或者函数的时候,我们可以在globals()的返回值字典中找到响应的映射: def A(): print("This is function A" ...

随机推荐

  1. CapsNet资源

    算法源码: https://github.com/xanderchf/pyCapsNet https://github.com/naturomics/CapsNet-Tensorflow 参考文章: ...

  2. 【PAT甲级】1079 Total Sales of Supply Chain (25 分)

    题意: 输入一个正整数N(<=1e5),表示共有N个结点,接着输入两个浮点数分别表示商品的进货价和每经过一层会增加的价格百分比.接着输入N行每行包括一个非负整数X,如果X为0则表明该结点为叶子结 ...

  3. Activiti工作流学习之概述(一)

    一.工作流介绍 我第一次听到这个词,是蒙逼的,再看百度百度,更傻眼了,完全说的不像人话啊,举几个生活中的例子,就明白多了比如:请假.报销等等,如果文字太过抽象,请看图: 二.工作流引擎 Process ...

  4. sort的使用

    sort主要是用来排序的,可以用自定义的函数进行比较,也可以用系统的4中函数进行比较,即less(),greater(),less_equal(),greater_equal().但是我试了一下,发现 ...

  5. Spring Security教程之session管理

    1.1     检测session超时 1.2     concurrency-control 1.3     session 固定攻击保护 Spring Security通过http元素下的子元素s ...

  6. SpringBoot与Shiro整合

    一.数据库设计 ​ 这里主要涉及到五张表:用户表,角色表(用户所拥有的角色),权限表(角色所涉及到的权限),用户-角色表(用户和角色是多对多的),角色-权限表(角色和权限是多对多的).表结构建立的sq ...

  7. Node.js介绍、优势、用途

    一.Node.js介绍Node.js是一个javascript运行环境.它让javascript可以开发后端程序,实现几乎其他后端语言实现的所有功能,可以与PHP.Java.Python..NET.R ...

  8. 如果谷歌浏览器突然打不开网页,而且显示:"网页可能暂时无法连接,或者它已永久性地移动到了新网址,返回ERR_TUNNEL_CONNECTION_FAILED",怎么办?用这个方法,亲试有效!!!

    打开cmd: 依次输入: ipconfig /flushdnsnbtstat –rnetsh int ip resetnetsh winsock reset 效果图 然后我的浏览器就能正常使用了,很有 ...

  9. 「CF197B Limit」

    题目撞名 题目大意: 给出两个函数 \(P(x),Q(x)\). \(P(x)=a_0 \times x^N+a_1 \times x^{N-1}+a_2 \times x^{N-2} \cdots ...

  10. 640js 的css 在750js 下用

    <script> // 640js的css样式调整至750js $(function(){ function fontsize640to750(){ var font640=$('html ...