python 入门基础24 元类、单例模式
内容目录:
一、元类
二、单例模式
一、元类
1 什么是元类:
源自一句话:在python中,一切皆对象,而对象都是由类实例化得到的
class OldboyTeacher:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def score(self):
print('%s is scoring' %self.name)
# tea1=OldboyTeacher('egon',18,'male')
# # print(type(tea1))
# print(type(OldboyTeacher))
# 对象tea1是调用OldboyTeacher类得到的,如果说一切皆对象,那么OldboyTeacher也是一个对象,只要是对象
# 都是调用一个类实例化得到的,即OldboyTeacher=元类(...),内置的元类是type
2.关系:
1. 调用元类---->自定义的类
2. 调用自定义的类---->自定义的对象
3.创建自定义类
自定义类的三个关键组成部分:
1. 类名
2. 类的基类们
3. 类的名称空间
class关键字创建自定义类的底层的工作原理,分为四步
1. 先拿到类名:'OldboyTeacher'
2. 再拿到类的基类们:(object,)
3. 然后拿到类的名称空间???(执行类体代码,将产生的名字放到类的名称空间也就是一个字典里,补充exec)
4. 调用元类实例化得到自定义的类: OldboyTeacher=type('OldboyTeacher',(object,),{...})
不依赖class关键字创建一个自定义类
# 1. 拿到类名
class_name='OldboyTeacher'
#2. 拿到类的基类们:(object,)
class_bases=(object,)
#3. 拿到类的名称空间
class_dic={}
class_body="""
school = 'Oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def score(self):
print('%s is scoring' %self.name)
"""
exec(class_body,{},class_dic)
print(class_dic)
#4. 调用type得到自定义的类
OldboyTeacher=type(class_name,class_bases,class_dic)
print(OldboyTeacher)
# print(OldboyTeacher.school)
# print(OldboyTeacher.score)
tea1=OldboyTeacher('egon',18,'male')
print(tea1.__dict__)
5.模板
# class Mymeta(type): #但凡继承了type的类才能称之为自定义的元类,否则就是只是一个普通的类
# def __init__(self,class_name,class_bases,class_dic):
# print(self)
# print(class_name)
# print(class_bases)
# print(class_dic)
#
# class OldboyTeacher(object,metaclass=Mymeta): #OldboyTeacher=Mymeta('OldboyTeacher',(object,),{...})
# school = 'Oldboy'
#
# def __init__(self,name,age,sex):
# self.name=name
# self.age=age
# self.sex=sex
#
# def score(self):
# print('%s is scoring' %self.name)
控制类的产生
1.类名必须用驼峰体
2.类体必须有文档注释,且文档注释不能为空
总结:对象之所以可以调用,是因为对象的类中有一个函数__call__
推导:如果一切皆对象,那么OldboyTeacher也是一个对象,该对象之所可以调用,肯定是这个对象的类中也定义了一个函数__call__
二、单例模式
1.什么是单例
单例:一个类只能产生一个实例
2. 为什么要有单例:
1.该类需要对象的产生
2.对象一旦产生,在任何位置再实例化对象,只能得到第一次实例化出来的对象
3.实现单例的方法:
# ----------------------------------------------------------------------
# 方式一:模块
class Songs():
pass
# s1 = Songs()
# s2 = Songs()
# print(s1, s2)
# 对外提供的对象
song = Songs()
# ----------------------------------------------------------------------
# 方式二:类方法
class Songs():
__instance = None
@classmethod
def getInstance(cls):
# 对象没有创建返回,有直接返回
if cls.__instance == None:
cls.__instance = cls()
return cls.__instance
# 约定别用 类名() 来实例化对象,用类方法来获取唯一对象
# s1 = Songs()
# s2 = Songs()
# print(s1, s2)
s1 = Songs.getInstance()
s2 = Songs.getInstance()
print(s1, s2)
# ----------------------------------------------------------------------
# 方式三:类初始化时对标志进行判断
class Songs:
__instance = None
def __new__(cls, song_name, *args, **kwargs):
if cls.__instance == None:
cls.__instance = object.__new__(cls)
cls.__instance.song_name = song_name
return cls.__instance
def change_song(self, song_name):
self.song_name = song_name
s1 = Songs('菊花爆满山')
s2 = Songs('感觉身体被掏空')
print(s1.song_name, s2.song_name) # 菊花爆满山 菊花爆满山
s2.change_song('感觉身体被掏空')
print(s1.song_name, s2.song_name) # 感觉身体被掏空 感觉身体被掏空
# ----------------------------------------------------------------------
# 方式四: 装饰器装饰类
def outer(cls):
_instance = None
def inner(*args, **kwargs):
nonlocal _instance
if _instance == None:
_instance = cls(*args, **kwargs)
return _instance
return inner
@outer # Songs = outer(Songs)
class Songs:
pass
s1 = Songs()
s2 = Songs()
print(s1, s2)
# ----------------------------------------------------------------------
# 方式五: 元类实现
class SingleMeta(type):
__instance = None
def __call__(cls, *args, **kwargs):
if SingleMeta.__instance == None:
SingleMeta.__instance = object.__new__(cls)
cls.__init__(SingleMeta.__instance, *args, **kwargs)
return SingleMeta.__instance
class Songs(metaclass=SingleMeta):
def __init__(self):
pass
pass
s1 = Songs()
s2 = Songs()
print(s1, s2)
python 入门基础24 元类、单例模式的更多相关文章
- python基础——使用元类
python基础——使用元类 type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello. ...
- python 面向对象进阶之元类metaclass
一:知识储备 exec exec:三个参数 参数一:字符串形式的命令 参数二:全局作用域(字典形式),如果不指定,默认为globals() 参数三:局部作用域(字典形式),如果不指定,默认为local ...
- python入门学习:8.类
python入门学习:8.类 关键点:类 8.1 创建和使用类8.2 使用类和实例8.3 继承8.4 导入类 8.1 创建和使用类 面向对象编程是最有效的软件编写方法之一.在面向对象编程中,你编写 ...
- 神级程序员通过两句话带你完全掌握Python最难知识点——元类!
千万不要被所谓"元类是99%的python程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
- Python 入门基础6 --字符编码、文件操作1
今日内容: 1.字符编码 2.字符与字节 3.文件操作 一.字符编码 了解: cpu:将数据渲染给用户 内存:临时存放数据,断电消失 硬盘:永久存放数据,断电后不消失 1.1 什么是编码? 人类能够识 ...
- Python入门基础学习 三
Python入门基础学习 三 数据类型 Python区分整型和浮点型依靠的是小数点,有小数点就是浮点型. e记法:e就是10的意思,是一种科学的计数法,15000=1.5e4 布尔类型是一种特殊的整形 ...
- Python入门基础学习 二
Python入门基础学习 二 猜数字小游戏进阶版 修改建议: 猜错的时候程序可以给出提示,告诉用户猜测的数字偏大还是偏小: 没运行一次程序只能猜测一次,应该提供多次机会给用户猜测: 每次运行程序,答案 ...
- Python入门基础学习 一
Python入门基础学习 一 Python下载及安装 下载地址:https://www.python.org/,选择最新的版本下载 稍等一会,安装完成. 简单语句 从idle启动Python:IDLE ...
- Python基础:元类
一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...
随机推荐
- BZOJ2819Nim——树链剖分+线段树+Nim游戏
题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...
- jQuery文档处理总结
<!DOCTYPE html> <html lang="cn"> <head> <meta charset="UTF-8&quo ...
- ef 仓储模式
构建一个仓储模式. Model 大家自己创建就行了,上个图,就不多说了(我是code first) IDAL namespace IDAL { public interface IBaseReposi ...
- openfalcon架构及相关服务配置详解
一:openfalcon组件 1.falcon-agent 数据采集组件 agent内置了一个http接口,会自动采集预先定义的各种采集项,每隔60秒,push到transfer. 2.transfe ...
- Sabotage UVA - 10480 (输出割边)
题意:....emm...就是一个最小割最大流,.,...用dinic跑一遍.. 然后让你输出割边,就是 u为能从起点到达的点, v为不能从起点到达的点 最后在残余路径中用dfs跑一遍 能到达的路 ...
- 自学Python6.2-类、模块、包
自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...
- luogu2607/bzoj1040 [ZJOI2008]骑士 (基环树形dp)
N个点,每个点发出一条边,那么这个图的形状一定是一个基环树森林(如果有重边就会出现森林) 那我做f[0][x]和f[1][x]分别表示对于x子树,x这个点选还是不选所带来的最大价值 然后就变成了这好几 ...
- 【ATcoder】Xor Sum 2
题目大意:给定一个 N 个点的序列,求有多少个区间满足\(\oplus_{i=l}^ra[i]=\sum\limits_{i=l}^ra[i]\). 题解: 小结论:\(a\oplus b=a+b\r ...
- BellmanFord 最短路
时间复杂度:O(VE) 最多循环V次,每次循环对每一条边(共E条边)判断是否可以进行松弛操作 最多V次:一个点的最短路,最多包含V-1个点(不包含该点), 如d1->d2->d3-> ...
- 获取Methods成员方法类
位于java.lang.reflect.Method包中 getModifiers() 成员方法的修饰符 getName() 成员方法的名字 getReturnType() 成员方法的声明类型 get ...