python基础--反射、元类、单例设计模式
反射:reflect,反射指的是一个对象应该具备可以检测、修改、增加自身属性的能力,反射就是通过字符串操作属性
hasattr(对象,带查询的属性名称)
判断某个对象中是否存在某个属性
getattr
从指定对象中取出属性,第三个参数为默认值,当参数不存在时返回的就是默认值
setattr
为对象添加新的属性
delattr
从对象中删除属性
使用场景:
反射其实就是对属性的增删改查,但是如果直接用dict来操作的话,语法繁琐,而且不是很好理解,另外一个主要的问题是,如果对象不是我自己写的是另一方提供的,我就必须要判断这个对象是否满足我的要求,也就是是否是我要的属性和方法
框架的基石:
原因: 因为框架的设计者,不可能提前知道你的对象到底是怎么设计的,所以你提供给框架的对象 必须通过判断验证之后才能正常使用,判断验证就是反射要做的事情,当然通过__dict__也是可以实现的, 其实这些方法也就是对__dict__的操作进行了封装,
元类:metaclass
是什么:就是用于创建类的类,万物皆是对象,当然类也是对象
对象是通过类实例化产生的,如果类也是对象的话,必然类对象也是有另一个类实例化产生的
默认情况下所有累的元类都是type
好处:高度的自定义一个类,类也是对象,也有自己的类
__call__方法:当你调用对象时会自动执行元类中的__call__方法,并将这个类本身作为第一个参数传入,以及后面的一堆参数, 当覆盖元类中的call之后,这个类就无法产生对象,必须调用super().__call__来完成对象的创建并返回其返回值
使用场景:
当你想要控制对象的创建过程时,就需要覆盖__call__方法
案例:将所有属性名称转换为大写
class Mytype(type):
def __call__(self, *args, **kwargs):
new_args = []
for i in args:
new_args.append(i.upper()) return super().__call__(*new_args, **kwargs) class Person(metaclass=Mytype):
def __init__(self, name):
self.name = name p = Person('william')
print(p.name)
一旦覆盖了call之后,就必须要调用父类的call方法来产生对象并且返回这个对象
__init__方法:
使用场景:
当你想要控制类的创建过程时,就覆盖__init__方法
__new__方法:
当你要创建对象时,会首先执行元类中的__new__方法,拿到一个空对象,然后自动调用__init__来对这个类进行初始化操作
注意:如果你覆盖了该方法就必须保证new方法有返回值并且是对应的类对象
class Meta(type): def __new__(cls, *args, **kwargs):
print(cls) # 元类自己
print(args) # 创建类需要的几个参数 类名,基类,名称空间
print(kwargs) #空的
print("new run")
# return super().__new__(cls,*args,**kwargs)
obj = type.__new__(cls,*args,**kwargs)
return obj
def __init__(self,a,b,c):
super().__init__(a,b,c)
print("init run")
class A(metaclass=Meta):
pass
print(A)
单例设计模式:
使用原因:单例是为了节省资源,当一个类的所有对象属性全部相同时,那这时候就没有必要创建多个对象了
class meta(type):
def __call__(self, *args, **kwargs):
if hasattr(self, "obj"):
return getattr(self, "obj")
obj = super().__call__(*args, **kwargs)
self.obj = obj
print('创建了一个....')
return obj class Student(metaclass=meta):
def __init__(self, name):
self.name = name s1 = Student('william')
s2 = Student('william')
s3 = Student('william')
s4 = Student('william')
python基础--反射、元类、单例设计模式的更多相关文章
- python基础——使用元类
python基础——使用元类 type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello. ...
- Python基础:元类
一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...
- 29 内置方法 eval | exec 元类 单例
eval与exec内置方法 将字符串作为执行目标,得到响应结果 eval常用作类型转换:该函数执行完有返回值 exec拥有执行更复杂的字符串:可以形成名称空间 eval内置函数的使用场景: 1.执 ...
- Python基础:新式类的属性访问
一.概述 二.准备工作 1.讨论对象 2.名词解释 三.实例绑定的属性访问 1.获取属性 一般规则 参考源码 示例验证 2.设置属性 一般规则 参考源码 示例验证 3.删除属性 一般规则 参考源码 示 ...
- JAVA_SE基础——38.单例设计模式
本文继续介绍23种设计模式系列之单例模式. 我们在javaSE的基础学习中,会讲到:单例设计模式.模板设计模式.装饰者设计模式.观察者设计模式.工厂设计模式 我以后随着水平的提高,我会专门开个分类写设 ...
- python小总结3(异常、单例设计模式)
一.异常 AttributeError:试图访问一个对象没有的成员[属性和方法] ValueError:值错误,传入了一个不期望的值 ImportError:无法导入模块或者包:基本上路径问题 Ind ...
- Python中的单例设计模式
1)设计模式: 是前人工作的总结和提炼.通常,被人们广泛流传的设计模式. 某一问题的特定解决方案,使用设计模式是为了可重用代码,是代码更容易被人理解, 增加代码的可用性. 2)单例设计模式: ...
- Python——单例设计模式
单例设计模式: 让类创建的对象,在系统中只有唯一的实例, 使用python类内置的__new__()方法实现,__new__()方法在创建对象时会被自动调用,通过重写__new__()方法,使得无论用 ...
- python学习【第十篇】单例设计模式
单例设计模式 目的:让类创建对象,在系统中只有唯一的实例,让每一次创建的对象返回的内存地址都是相同的. __new__方法 使用类名创建对象时,python解释器首先会调用__new__方法为对象分配 ...
随机推荐
- 「题解」:[BZOJ4558]方
问题: 方 时间限制: 2 Sec 内存限制: 256 MB 题面 题目描述 上帝说,不要圆,要方,于是便有了这道题.由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形 上帝把我们派到了一 ...
- Error configuring application listener of class [org.springframework.web.util.Log4jConfigListener]
1.启动项目发现如下错误: 严重: Error configuring application listener of class [org.springframework.web.util.Log4 ...
- C++Builder 常用String
关于AnsiSting的使用大全(1) arrow: Ansistring 转 char 代码: void __fastcall TForm1::Button1Click(TObject *Sende ...
- mysql 主从,双主同步
1.创建用户并设置远程访问授权 1). A上添加: //ip地址为B的ip地址,用于B访问 ' with grant option; 2). B上添加://ip地址为A的ip地址,用于A访问 ' wi ...
- Android 之 BroadcaseReceiver
1.在AndroidManifest.xml中注册 <receiver android:name=".MyReceiver"> <intent-filter &g ...
- HOOK NtCreateSection
本程序使用了hde32反汇编引擎,所以性能更加稳定! #pragma once #include <ntddk.h> NTSYSAPI NTSTATUS NTAPI NtCreateSec ...
- Android基础控件RatingBar星级评分条的使用
1.简介 RatingBar继承ProgressBar,除了ProgressBar的属性外还有特有属性: android:isIndicator:是否用作指示,用户无法更改,默认false andro ...
- <随便写>佛祖,哈哈!
print(" _ooOoo_ ") print(" o8888888o ") print(" 88 . 88 ") print(" ...
- Property 'validate' does not exist on type 'Element | Element[] | Vue | Vue[]'. Property 'valid...
使用vue-cli 3.0+Element-ui时候,调用form表单校验时候出现的问题是: Property 'validate' does not exist on type 'Element | ...
- vue使用远程在线更新代码
一.main.js import Vue from 'vue' import App from './App' import router from './router' import Vuex fr ...