python 元类的call_python3 全栈开发 - 内置函数补充, 反射, 元类,__str__,__del__,exec,type,__call__方法...
python3 全栈开发 - 内置函数补充, 反射, 元类,__str__,__del__,exec,type,__call__方法
一, 内置函数补充
1,isinstance(obj,cls)检查是否 obj 是否是类 cls 的对象classFoo(object):
pass
obj=Foo()
print(isinstance(obj,Foo))#结果为 True
2,issubclass(sub, super)检查 sub 类是否是 super 类的派生类classFoo(object):
pass
classBar(Foo):
pass
print(issubclass(Bar,Foo))#结果为 True
二, 反射
1 , 什么是反射
反射的概念是由 Smith 在 1982 年首次提出的, 主要是指程序可以访问, 检测和修改它本身状态或行为的一种能力(自省). 这一概念的提出很快引发了计算机科学领域关于应用反射性的研究. 它首先被程序语言的设计领域所采用, 并在 Lisp 和面向对象方面取得了成绩.
2 ,python 面向对象中的反射: 通过字符串的形式操作对象相关的属性. python 中的一切事物都是对象(都可以使用反射)
四个可以实现自省的函数:
hasattr,getattr,setattr,delattr
下列方法适用于类和对象(一切皆对象, 类本身也是一个对象)# 1,hasattr
# print(hasattr(People,'country')) #True
# print('country' in People.__dict__) #不知道 hasattr 方法时, 用的方法
# print(hasattr(obj,'name')) #True
# print(hasattr(obj,'country')) #True
# print(hasattr(obj,'tell')) #True
# 2,getattr
# x=getattr(People,'country1',None) #查找指定属性, 没有此属性 (提前预防报错写 None) 显示 None, 有就返回值
# print(x)
# f=getattr(obj,'tell',None)#obj.tell
# print(f == obj.tell) #True
# f() #正常的调用函数
# obj.tell()
# 3,setattr
# People.x=111
# setattr(People,'x',111) #添加 x 属性, 值为 111
# print(People.x)
# obj.age=18
# setattr(obj,"age",18) # 添加 age 属性, 值为 18
# print(obj.__dict__)
# 4,delattr
# del People.country #原始的方法
# delattr(People,"country")
# print(People.__dict__)
# del obj.name
# delattr(obj,"name")
# print(obj.__dict__)
三,__str__classPeople:
def__init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def__str__(self):
# print('========>')
return''%(self.name,self.age,self.sex)
obj=People('duoduo',18,'male')
print(obj)#print(obj.__str__()) 在 print 时触发__str__
四, __del__
当对象在内存中被释放时, 自动触发执行.
注: 如果产生的对象仅仅只是 python 程序级别的(用户级), 那么无需定义__del__, 如果产生的对象的同时还会向操作系统发起系统调用, 即一个对象有用户级与内核级两种资源importtime
classPeople:
def__init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def__del__(self):# 在对象被删除的条件下, 自动执行
print('__del__')
obj=People('duoduo',18,'male')
#del obj #obj.__del__() #先删除的情况下, 直接执行__del__
time.sleep(5)#可以更形象的看出在资源回收前执行__del__
典型的应用场景:
创建数据库类, 用该类实例化出数据库链接对象, 对象本身是存放于用户空间内存中, 而链接则是由操作系统管理的, 存放于内核空间内存中
当程序结束时, python 只会回收自己的内存空间, 即用户态内存, 而操作系统的资源则没有被回收, 这就需要我们定制__del__, 在对象被删除前向操作系统发起关闭数据库链接的系统调用, 回收资源
这与文件处理是一个道理:f=open('a.txt')#做了两件事, 在用户空间拿到一个 f 变量, 在操作系统内核空间打开一个文件
delf#只回收用户空间的 f, 操作系统的文件还处于打开状态
# 所以我们应该在 del f 之前保证 f.close()执行, 即便是没有 del, 程序执行完毕也会自动 del 清理资源, 于是文件操作的正确用法应该是
f=open('a.txt')
读写...f.close()
# 很多情况下大家都容易忽略 f.close, 这就用到了 with 上下文管理
classMyOpen:#自己写个打开读文件类, 封装内置的 open
def__init__(self,filepath,mode="r",encoding="utf-8"):
self.filepath=filepath
self.mode=mode
self.encoding=encoding
self.fobj=open(filepath,mode=mode,encoding=encoding)#申请系统内存
def__str__(self):
msg="""
filepath:%s
mode:%s
encoding:%s
"""%(self.filepath,self.mode,self.encoding)
returnmsg
def__del__(self):
self.fobj.close()
f=MyOpen('aaa.py',mode='r',encoding='utf-8')
# print(f.filepath,f.mode,f.encoding)
# print(f)
# print(f.fobj)
res=f.fobj.read()#一样可以读
print(res)
五, exec# 例子 一
code="""
#global x #shsh 声明 x 为全局变量
x=0
y=2
"""global_dic={'x':100000}
local_dic={}#字符串中声明全局就是全局, 不声明就是局部
exec(code,global_dic,local_dic)
#
# print(global_dic)
# print(local_dic)
# 例子 二
# code="""
# x=1
# y=2
# def f1(self,a,b):
# pass
# """
# local_dic={}
# exec(code,{},local_dic)
# print(local_dic)
六, 元类
1, 什么是元类:
类的类就是元类# 我们用 class 定义的类使用来产生我们自己的对象的
# 内置元类 type 是用来专门产生 class 定义的类的
# 一切皆为对象:
# Chinese=type(...)
classChinese:
country="China"
def__init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
defspeak(self):
print('%s speak Chinese'%self.name)
# print(Chinese)
# p=Chinese('duoduo',18,'male')
# print(type(p)) #最上层的类 type
# print(type(Chinese))
2, 用内置的元类 type, 来实例化得到我们的类#2, 用内置的元类 type, 来实例化得到我们的类
class_name='Chinese'
class_bases=(object,)
lass_body="""country="China"
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def speak(self):
print('%s speak Chinese' %self.name)
"""
class_dic={}
exec(class_body,{},class_dic)
#类的三大要素
# print(class_name,class_bases,class_dic)
Chinese=type(class_name,class_bases,class_dic)
# print(Chinese)
p=Chinese('duoduo',18,'male')
# print(p.name,p.age,p.sex)
3,__call__
对象后面加括号, 触发执行.
注: 构造方法的执行是由创建对象触发的, 即: 对象 = 类名() ; 而对于 __call__ 方法的执行是由对象后加括号触发的, 即: 对象() 或者 类()()classFoo:
def__init__(self):
pass
def__str__(self):
return'123123'
def__del__(self):
pass
# 调用对象, 则会自动触发对象下的绑定方法__call__的执行,
# 然后将对象本身当作第一个参数传给 self, 将调用对象时括号内的值
#传给 * args 与 **kwargs
def__call__(self,*args,**kwargs):
print('__call__',args,kwargs)
obj=Foo()
# print(obj)
obj(1,2,3,a=1,b=2,c=3)#
4, 自定义元类classMymeta(type):
# 来控制类 Foo 的创建
def__init__(self,class_name,class_bases,class_dic):#self=Foo
# print(class_name)
# print(class_bases)
# print(class_dic)
ifnotclass_name.istitle():#加上判断
raiseTypeError('类名的首字母必须大写')
ifnotclass_dic.get('__doc__'):
raiseTypeError('类中必须写好文档注释')
super(Mymeta,self).__init__(class_name,class_bases,class_dic)
# 控制类 Foo 的调用过程, 即控制实例化 Foo 的过程
def__call__(self,*args,**kwargs):#self=Foo,args=(1111,) kwargs={}
# print(self)
# print(args)
# print(kwargs)
#1 造一个空对象 obj
obj=object.__new__(self)
#2, 调用 Foo.__init__, 将 obj 连同调用 Foo 括号内的参数一同传给__init__
self.__init__(obj,*args,**kwargs)
returnobj
#Foo=Mymeta('Foo',(object,),class_dic)
classFoo(object,metaclass=Mymeta):
"""文档注释"""
x=1
def__init__(self,y):
self.Y=y
deff1(self):
print('from f1')
obj=Foo(1111)#Foo.__call__()
# print(obj)
# print(obj.y)
# print(obj.f1)
# print(obj.x)
5, 单例模式importsettings#调用配置文件的 IP,PORT
classMySQL:
__instance=None
def__init__(self,ip,port):
self.ip=ip
self.port=port
@classmethod#绑定方法
defsingleton(cls):
ifnotcls.__instance:
obj=cls(settings.IP,settings.PORT)
cls.__instance=obj
returncls.__instance
obj1=MySQL('1.1.1.2',3306)
obj2=MySQL('1.1.1.3',3307)
obj3=MySQL('1.1.1.4',3308)
# obj4=MySQL(settings.IP,settings.PORT)
# print(obj4.ip,obj4.port)
obj4=MySQL.singleton()
obj5=MySQL.singleton()
obj6=MySQL.singleton()
print(obj4isobj5isobj6)#Ture
来源: https://www.cnblogs.com/ManyQian/p/8868350.html
python 元类的call_python3 全栈开发 - 内置函数补充, 反射, 元类,__str__,__del__,exec,type,__call__方法...相关推荐
- delstr函数python_python3全栈开发-内置函数补充,反射,元类,__str__,__del__,exec,type,__call__方法详解...
一.内置函数补充 1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象 classFoo(object):passobj=Foo()print(isinstance(obj ...
- python内置函数面向对象_Pyhton——面向对象进阶二:类的内置函数补充、描述符...
Pyhton--面向对象进阶二: 一.类的内置函数补充 1.isinstance(obj,cls)--检查obj是否是该类的对象 class Hoo: def __init__(self,name,t ...
- and true和if都是python语言的保留字_python自学 第三章 python语言基础之保留字、标识符与内置函数...
一.保留字(关键字) 保留字是 python 语言中一些已经被赋予特定意义的单词,这就要求开发者在开发程序时,不能用这些保留字作为标识符给变量.函数.类.模板以及其他对象命名. Python 保留字一 ...
- Python中冷门但非常好用的内置函数
Python中有许多内置函数,不像print.len那么广为人知,但它们的功能却异常强大,用好了可以大大提高代码效率,同时提升代码的简洁度,增强可阅读性 Counter collections在pyt ...
- python中求包含5的数_Python 内置函数 ( ) 可以返回列表、元组、字典、集合、字符串以及 range 对象中元素个数。_学小易找答案...
[简答题]实例1:求两数相除的结果. 先后输入2个数据,计算第一个数除以第二个数的结果. 要求能够处理输入数据为非数字.除数为零.文件末尾EndOfFile 和用户使用Ctrl + C 命令终止程序等 ...
- python字符串(连载二)|字符串内置函数原来还可以这么玩!
此系列连载涵盖 字符串,列表,字典,元组,集合等内置函数的基本用法.每次更新十个函数的基本用法.(建议收藏哈) 有福利哦,小编整理了些python学习资料,需要的自行领取!获取方式在文末哈! 目录: ...
- python 作用域从大到小排序_Python 内置函数、作用域、闭包、递归
一.内置函数如何使用 help()一下: 如想看min()咋用?在shell中:help(min) 二.部分内置函数 (一).排序:sorted() li = [(1, 2, 3, 4), (7, 8 ...
- python lambda 逻辑_Python之lambda表达式和内置函数
lambda表达式其实就是简化的函数表达式. 它只用于处理简单逻辑, 它会自动return数据 通常定义一个函数,按照以下形式:def func(arg): return arg +1 result ...
- 【Python基础】Python 打基础一定要吃透这 5 个内置函数
出品:Python数据之道 作者:Peter 编辑:Lemon 本文中介绍 Python 中 5 个高阶内置函数,它们不仅能够帮助我们了解 Python 的数据结构,同时也能加快数据处理的速度,体会到 ...
最新文章
- 多媒体容器格式概述①
- WF:要想绑到两个活动的属性值---依赖属性的定义方法
- builtins.ModuleNotFoundError: No module named ‘’scrapy.contrib‘’
- 屏蔽基于对话框的MFC程序中按下ESC关闭窗口的功能
- LeetCode 1130. 叶值的最小代价生成树(区间DP/单调栈贪心)
- 用string存取二进制数据
- 服务器指定网卡进行备份数据避免影响业务口
- 13 Zuul的配置
- 【附干货】卸载CAD后将注册表清理干净的方法及步骤
- 「职业解读」软件测试工程师
- 最新python腾讯文档界面自动打卡
- Splitter和Joiner使用手册
- 优化 | 线性化:0-1变量乘以连续变量的线性化
- 识读第三角视图(机械识图)
- win10 无限重启
- 指针式仪表自动读数与识别(四):非圆形表盘定位
- python 返回绝对值
- LeetCode 三维形体的表面积
- unity第三人称射击游戏_在游戏上第3部分完美的信息游戏
- ProxyCap +ccproxy 组合使用Socks5 实现代理服务器
热门文章
- 架空输电线路运行规程_架空输电线路杆塔金具的种类
- C++实现坐标的平移和旋转
- 网页按钮跳转位置_RPA工具BizRobo!之运用网页数据处理
- utxo模型_什么是UTXO?简析账户/余额模型和UTXO模型
- python网络爬虫的论文模板_Python简单网络爬虫实战—下载论文名称,作者信息(上)...
- BZOJ-3531-旅行
- SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机、状压DP)
- nginx rtmp 编码_基于Nginx的媒体服务器技术
- 当前记录集不支持更新_微信现已正式支持修改微信号!微信7.0.16内测版更新(附下载)...
- python判断是否是完数_python判断是否完数