python面向对象之元类
元类
元类(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面向对象之元类的更多相关文章
- Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法
Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...
- Python面向对象之元类(metaclass)
点进来看就完事了铁汁!
- python基础——使用元类
python基础——使用元类 type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello. ...
- Python基础:元类
一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...
- [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式
使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...
- 什么是python中的元类
所属网站分类: python高级 > 面向对象 作者:goodbody 原文链接: http://www.pythonheidong.com/blog/article/11/ 来源:python ...
- Python中的元类(metaclass)
推荐+收藏:深刻理解Python中的元类(metaclass) 做一些笔记学习学习: 在大多数编程语言中,类就是用来描述如何生成一个对象的代码段,在Python中类也是一个对象,这个(类)对象自身拥有 ...
- Python面向对象之接口类(抽象类)
Python面向对象之接口类(抽象类):就是制定一个规范. 比如定义了一个接口类(抽象类)(他们是不可以进行实例化的,这就是他为什么是制定一个规范的原因). 他的定义是需要abc模块,要变的就是他的方 ...
- [Python之路] 元类(引申 单例模式)
一.类也是对象 当我们定义一个变量或者函数的时候,我们可以在globals()的返回值字典中找到响应的映射: def A(): print("This is function A" ...
随机推荐
- vscode 提示 Running save participants 无法保存文件
今天vscode提示一直在running save participants...中,无法保存文件 control + shift + p打开面板后,输入Reload with extensions ...
- JIT对锁的优化- 锁消除和锁粗化案例分析
锁消除和锁粗化案例分析 锁消除 直接上代码 /** * 描述: 锁粒度演示 * @author karl * @create 2020-02-11 14:38 */ public class MySy ...
- Java中引用类型、对象的创建与销毁
引用类型 在java中,除了基本数据类型之外的,就是引用数据类型了,引用指的是对象的一个引用,通过引用可以操作对象,控制对象,向对象发送消息. 简单来说,引用可以访问对象的属性,并调用对象的方法 创建 ...
- 15. 深入解析Pod对象(二):使用进阶
15. 深入解析Pod对象(二):使用进阶 15.1 Projected Volume,投射数据卷 备注:Projected Volume 是 Kubernetes v1.11 之后的新特性 在 Ku ...
- 吴裕雄 python 神经网络——TensorFlow 自定义损失函数
import tensorflow as tf from numpy.random import RandomState batch_size = 8 x = tf.placeholder(tf.fl ...
- MQTT 浏览器 mqttws31.min.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Codeforces Round #621 (Div. 1 + Div. 2) C. Cow and Message
Bessie the cow has just intercepted a text that Farmer John sent to Burger Queen! However, Bessie is ...
- Android 调用系统Email发送带多附件的邮件
转自:http://www.open-open.com/lib/view/open1347005126912.html 众所周知,在Android中调用其他程序进行相关处理,都是使用的Intent.当 ...
- org.springframework.data.redis.RedisConnectionFailureException
org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested ...
- [C++基本语法:从菜鸟变成大佬系列,就像1,2,3那么简单](七):C++的修饰符
修饰符是什么? C++允许char,int和double数据类型在它们之前有修饰符.修饰符用于改变基本类型的含义,以便更精确地满足各种情况的需要. 这里列出了数据类型修饰符: signed unsig ...