元类

元类(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. RTT学习之软件包

    网络工具集 (NetUtils) Ping 工具: 是一种网络诊断工具,用来测试数据包能否通过 IP 协议到达特定主机,依赖于LWIP,支持域名和IP访问: NTP 工具:NTP 是网络时间协议 (N ...

  2. python导入openpyxl报错问题,终于解决啦

    问题:折腾了一上午,安装.卸载openpyxl多次,cmd中明明显示安装成功,可python文件import时就是报错 1.安装openpyxl后,python文件导入一直报错,经过一上午的努力,终于 ...

  3. DAY1小题

    F 求逆序对的板子题 #include<cstdio> #define ll long long using namespace std; ; ll a[maxn],r[maxn],n; ...

  4. SqlHelper类编写前奏:DataReader关闭链接出现问题

    SqlHelper是一个执行数据库操作的助手类,但是当我们没学过DataSet之前,要想使用using搭配SqlConnection和SqlCommand写出一个真正独立的SqlHelper都是不太可 ...

  5. pdf.js的使用 (3)真实项目分享

    需求:a.jsp页面要做一个pdf的预览功能,我采用layer.open()弹窗的形式来预览pdf 1.在a.jsp点击文件然后弹出窗口(其实是弹出b.jsp) var lay=layer.open( ...

  6. 吴裕雄--天生自然Numpy库学习笔记:NumPy 排序、条件刷选函数

    numpy.sort() 函数返回输入数组的排序副本.函数格式如下: numpy.sort(a, axis, kind, order) 参数说明: a: 要排序的数组 axis: 沿着它排序数组的轴, ...

  7. Codeforces Round #611 (Div. 3) C

    There are nn friends who want to give gifts for the New Year to each other. Each friend should give ...

  8. CentOS7 安装 OpenCV 的一些问题解决办法

    由于强迫症,实在受不了root权限的旧gcc才能使用boost而普通权限却是最新版gcc,经过一番折腾后,终于把配置全部弄好了,实际上就只需要把新版gcc的各个文件放到系统找到旧gcc的地方,并建立新 ...

  9. 第二十九节: Asp.Net Core零散获取总结(不断补充)

    1. IWebHostEnvironment获取常用属性 (1).获取项目的根目录 _env.ContentRootPath 等价于 Directory.GetCurrentDirectory() ( ...

  10. ajax的XmlHttpRequest对象常用方法

    onreadystatechange用于检测readyState状态的改变,当readyState的状态发生改变的时候调用回调