python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法
1. 元类type
type:获取对象从属的类
Python中一切皆对象,类在某种意义上也是一个对象
Python中自己定义的类,以及大部分内置类,都是由type元类(构建类)实例化得来的
# type 获取对象从属于的类
print(type(A))
print(type(str))
print(type(dict))type与object的关系:
object类是type类的一个实例 print(type(object))
object类是type类的父类 print(issubclass(type,object))
2. 反射
定义:通过字符串操作对象的方式,程序对自己内部代码的一种自省方式
内置函数:hasattr getattr setattr delattr (attr 是属性的意思)
反射可以作用的对象:实例对象,类,本模块,其他模块
从对象角度应用反射
class A:
country = '中国'
def __init__(self,name,age):
self.name = name
self.age = age
def func(self):
print('in A func')
obj = A('张三',66) # hasattr: 判断有无属性
print(hasattr(obj,'name'))
print(hasattr(obj,'country')) # 报错
print(hasattr(obj,'func')) # 报错 # getattr: 获取属性
if hasattr(obj,'name'):
getattr(obj,'name') # setattr: 设置属性/delattr: 删除属性
setattr(obj,'sex','男')
delattr(obj,'name')从类的角度应用反射
class A:
country = '中国'
def __init__(self,name,age):
self.name = name
self.age = age
def func(self):
print(self)
print('in A func') if hasattr(A,'func'):
obj = A('张三', 26)
getattr(obj,'func')()
getattr(A,'func')(obj)从其他模块应用反射
import tbjx # 1. 找到tbjx对象的C类,实例化一个对象.
obj = getattr(tbjx,'C')('') # 2. 找到tbjx对象的C类,通过对C类这个对象使用反射取到area.
print(getattr(tbjx.C,'area')) # 3. 找到tbjx对象的C类,实例化一个对象,对对象进行反射取值.
obj = getattr(tbjx,'C')('张三')
print(obj.name)
print(getattr(obj,'name'))从当前模块应用反射
def func1():
print('in func1') def func2():
print('in func2') def func3():
print('in func3') def func4():
print('in func4') import sys
print(sys.modules[__name__])
getattr(sys.modules[__name__],'func1')()
getattr(sys.modules[__name__],'func2')()
getattr(sys.modules[__name__],'func3')() # 本模块的模块名:sys.modules[__name__]反射应用示例:
class User:
def login(self):
print('欢迎来到登录页面') def register(self):
print('欢迎来到注册页面') def save(self):
print('欢迎来到存储页面') choose_dic = {
1: User.login,
2: User.register,
3: User.save,
} while 1:
choose = input('请输入序号: \n1: 登录\n2: 注册\n3: 存储').strip()
obj = User()
choose_dic[int(choose)](obj)
3. 函数与类的区别
函数都是显性传参,方法都是隐形传参
class A:
@classmethod
def func(cls,a):
pass
@staticmethod
def func1():
pass A.func(666)
A.func()通过打印函数名的方式,区别什么是方法,什么是函数
def func1():
pass
class A:
def func(self):
pass
print(func1)
print(A.func)
obj = A()
print(obj.func) # 结果:
<function func1 at 0x000000A9C59C1EA0>
<function A.func at 0x000000A9C75DE268>
<bound method A.func of <__main__.A object at 0x000000A9C744D4A8>>可以借助模块判断类中的是方法还是函数
from types import FunctionType
from types import MethodType
def func():
pass
class A:
def func(self):
pass
obj = A()
print(isinstance(func,FunctionType)) # True
print(isinstance(A.func,FunctionType)) # True
print(isinstance(obj.func,FunctionType)) # False
print(isinstance(obj.func,MethodType)) # True
4. 特殊的双下方法
特殊的双下方法: 原本是开发python这个语言的程序员用的.源码中使用的,双下方法: 你不知道你干了什么就触发某个双下方法
# 1.__len__ len(b)执行b类从属父类的__len__方法,必须要有return int(返回值)
class B:
def __init__(self,name,age):
self.name = name
self.age =age
def __len__(self):
return len(self.__dict__) #
b = B('张三',28)
print(len(b)) # 2.__hash__ hash()触发__hash__双下方法
class A(object):
def __hash__(self):
return 123456
obj = A()
print(hash(obj)) # 3.__str__ 里边必须有return "字符串"类型 (优先级高于__repr__)
# - 打印对象的时候,会触发__str__方法
# - str转化也可以触发
class A:
def __init__(self,name,age):
self.name = name
self.age =age
def __str__(self):
print('触发str方法')
return f'姓名: {self.name} 年龄: {self.age}'
a = A('张三',35) # 打印对象触发__str__方法
print(f'{a.name} {a.age}')
print(a) # 直接str转化也可以触发.
print(str(a)) # 4.__repr__ 里边必须有return "字符串"类型
# - 打印对象的时候,会触发__repr__方法
class A:
def __init__(self,name,age):
self.name = name
self.age =age
def __repr__(self):
print(666)
return f'姓名: {self.name} 年龄: {self.age}' a = A('张三',35)
print(a)
print(repr(a)) # 5.__call__ 对象()触发对象从属类(父类)的__call__方法
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo()
obj() # 6.__eq__ 两对象==时触发,return True/false(可以返回数字,字符串 一般返回布尔值)
class A(object):
def __init__(self):
self.a = 1
self.b = 2 def __eq__(self,obj):
print('__eq__')
return True
x = A()
y = A()
print(x == y) # 7.__del__ 析构方法 回收对象时触发__del__方法
class A:
def __del__(self):
print('__del__')
obj = A()
del obj # 8.__new__ new一个对象(构造方法),实例化对象的时候会触发,对象是object类的__new__方法,产生了一个对象
class A(object):
def __init__(self):
print('in init function') def __new__(cls, *args, **kwargs):
print('in new function')
return object.__new__(A) # 对象是object类的__new__方法 产生了一个对象.
a = A() # 类名()
# 1. 先触发 object的__new__方法,此方法在内存中开辟一个对象空间.
# 2. 执行__init__方法,给对象封装属性. # def __init__(self):(不能写返回值,因为__new__已经有返回值了,不能同时接收两个返回值,只能接收__new__的返回值) # 9.__item__系列(4个)
# __getitem__ __setitem___ __delitem__ 对对象做类似于字典的(增删改查)触发__item__系列
class Foo:
def __init__(self,name):
self.name=name
def __getitem__(self, item):
# print(item)
# print(666)
return self.__dict__[item] def __setitem__(self, key, value):
# self.__dict__[key]=value
print(key)
print(value) def __delitem__(self, key):
print('del obj[key]时,我执行') f1=Foo('zhangsan')
f1['age']
f1[1] = 2
del f1[1] # 10.__enter__ __exit__ with 上下文管理(2个)
class A: def __init__(self, text):
self.text = text def __enter__(self): # 开启上下文管理器对象时触发此方法
self.text = self.text + '您来啦' # 第一步
print(11111)
return self # 必须!!!将实例化的对象返回f1 def __exit__(self, exc_type, exc_val, exc_tb): # 执行完上下文管理器对象f1时触发此方法
print(333) # 第三步
self.text = self.text + ',这就走啦' with A('大爷') as f1:
print(2222)
print(f1.text) # 第二步
print(f1.text) # 第四步 # 11.__iter__ for循环会触发此方法
class A:
def __init__(self,name):
self.name = name def __iter__(self):
for i in range(10):
yield i obj = A('张三')
for i in obj:
print(i) # 12.__getattr__(self,item),__setattr__(self,key,value),__delattr__
# obj.属性会触发__getattr__(self,item)方法
# obj.属性=123 会触发__setattr__(self,key,value)
# del obj.属性 就会触发__delattr__ 此方法
def func1():
pass
class A:
def func(self):
pass
print(func1)
print(A.func)
obj = A()
print(obj.func) # 结果:
<function func1 at 0x000000A9C59C1EA0>
<function A.func at 0x000000A9C75DE268>
<bound method A.func of <__main__.A object at 0x000000A9C744D4A8>>
python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法的更多相关文章
- Python面向对象之反射,双下方法
一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...
- Python反射和内置方法(双下方法)
Python反射和内置方法(双下方法) 一.反射 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发 ...
- Python面向对象 | 双下方法
定义:双下方法是特殊方法,他是解释器提供的.由双下划线+方法名+双下划线 .它具有特殊意义的方法,双下方法主要是python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更 ...
- Python 入门 之 双下方法
Python 入门 之 双下方法 1.双下方法 定义:双下方法是特殊方法,它是解释器提供的 由双下划线加方法名加双下划线 方法名的具有特殊意义的方法,双下方法主要是python源码程序员使用的,我 ...
- Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法
Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...
- python 面向对象十二 元类
一.类也是对象 只要使用关键字class,Python解释器在执行的时候就会创建一个对象.下面的代码段: class ObjectCreator(object): pass 将在内存中创建一个对象,名 ...
- python 面向对象专题(四):封装、多态、鸭子类型、类的约束、super
https://www.cnblogs.com/liubing8/p/11321099.html 目录 Python面向对象04 /封装.多态.鸭子类型.类的约束.super 1. 封装 2. 多态 ...
- day26——tyoe元类与object的联系、反射、函数与方法的区别、双下方法
day26 type元类与object联系 type 获取对象从属于的类 python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类,都是由type元类(构 ...
- 百万年薪python之路 -- 面向对象之 反射,双下方法
面向对象之 反射,双下方法 1. 反射 计算机科学领域主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) python面向对象中的反射:通过字符串的形式操作对象相关的属性.python ...
随机推荐
- Cookie和localStorage的查询、设置、修改及删除
感谢:链接(视频讲解很详细) cookie:是一种字符串表示的数据,用于在本地记录用户的基本信息(账号,密码等),具有时限性. 数据的具体内容: (图源上文视频链接) localStorage:与co ...
- ado.net Web前端:关于JavaScript知识点的简单梳理
学习js:1.htmml2.cssjs+html+css == html5 js的组成:1).ecamscript ES是js的标准,js 是es 的实现2)文档对象模型(Document Objec ...
- VScode Doxygen与Todo Tree插件的使用与安装
VScode Doxygen与Todo Tree插件的使用与安装 引言 程序中代码注释的规范和统一性是作为工程人员必不可少的技能,本文在Visual Studio Code的环境下简单介绍Doxyge ...
- 关于自动寻路(Navigation)的初级总结
1.使用Nav Mesh Link组件 该组件会实现寻路者从Start跳向end点 注意Player会优先选择最佳路线,且Start,End两个物体都应该在Walkable的区域上 2.使用Nav M ...
- 手把手教你学Numpy,搞定数据处理——收官篇
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Numpy专题第6篇文章,我们一起来看看Numpy库当中剩余的部分. 数组的持久化 在我们做机器学习模型的研究或者是学习的时候,在完成 ...
- Pikachu靶场SQL注入刷题记录
数字型注入 0x01 burp抓包,发送至repeater 后面加and 1=1,and 1=2 可判断存在注入 0x02 通过order by判断字段数,order by 2 和order by 3 ...
- 入门大数据---Spark_Streaming整合Flume
一.简介 Apache Flume 是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中.Spark Straming 提供了以下两种方式用于 ...
- 前端基础:”天龙八步“细说浏览器输入URL后发生了什么
参考:https://www.xuecaijie.com/it/157.html#1Q64p5DeC8dKFF 本文摘要: 1.DNS域名解析: 2.建立TCP连接: 3.发送HTTP请求: 4.服务 ...
- 【博弈】HDU - 5963 朋友
题目 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始,双 ...
- Kubernetes 两步验证 - 使用 Serverless 实现动态准入控制
作者:CODING - 王炜 1. 背景 如果对 Kubernetes 集群安全特别关注,那么我们可能想要实现这些需求: 如何实现 Kubernetes 集群的两步验证,除了集群凭据,还需要提供一次性 ...