python面向对象 : 反射和内置方法
一. 反射
1. isinstance()和issubclass()
isinstance( 对象名, 类名) : 判断对象所属关系,包括父类 (注:type(对象名) is 类名 : 判断对象所属关系,只包括当前的类.)
issubclass(类名, 类名) : 判断类与类之间的继承关系
class A:passclass B(A):passb = B() print(isinstance(b, B)) # True 判断对象b是否属于B类 print(isinstance(b, A)) # True 判断对象b是否属于A类 print(type(b) is B) # True 判断对象b是否属于B类 print(type(b) is A) # False 判断对象b是否属于A类print(issubclass(A, B)) # False 判断A是不是B的子类 print(issubclass(B, A)) # True 判断B是不是A的子类
2. 反射
反射 : 用字符串数据类型的变量名来访问这个变量的值. python中的一切事物都是对象(都可以使用反射)
反射的方法 : getattr , hasattr, setattr, delattr
(1) getattr
getattr 接收2个参数,前面的是一个对象或者模块,后面的是一个字符串.
语法 : 命名空间.XXX == getattr(命名空间,'XXX')
#从类的角度看:class A:name = 'jack'@classmethoddef func(cls):print(666)@staticmethoddef func1():print(777)# 反射查看静态属性 print(A.name) # jack print(getattr(A, 'name')) # jack # 反射调用方法 A.func() # 666 print(getattr(A, 'func')) # <bound method A.func of <class '__main__.A'>> 内存地址 getattr(A, 'func')() # 666 类方法 A.func1() # 777 print(getattr(A, 'func1')) # <function A.func1 at 0x000002436F709620> 内存地址 getattr(A, 'func1')() # 777 静态方法
# 从对象的角度来看class A:NAME = 'STEVE' # 全局变量和类中的静态属性最好全大写 @classmethoddef func(cls):print(666)@staticmethoddef func1():print(777)a = A() # 反射查看静态属性 print(getattr(a, 'NAME')) # STEVE # 反射调用方法# 类方法 getattr(a, 'func')() # 666# 静态方法 getattr(a, 'func1')() # 777
# 从模块的的角度# 导入系统模块 import os # 导入os模块 os模块是别人写好的python代码的结合 os.rename('12', 'hello') # 把文件为'12'的文件名改为'hello' getattr(os, 'rename')('hello', '12') # 把文件为'hello'的文件名改为'12' ==>> os.rename# 导入自己的模块def func1():print(666) def func2():print(777)import sys # 是一个模块,这个模块里的所有的方法都是和python解释器相关的 print(sys.modules) # 这个方法 表示所有在当前这个python程序中导入的模块 # 可以找到本文件的模块地址(字典类型): '__main__' from 'D:/pycharm/练习/week05/new21.py'> print(sys.modules['__main__']) # <module '__main__' from 'D:/pycharm/练习/week05/new21.py'> file = sys.modules['__main__'] file.func1() # 666 file.func2() # 777 getattr(file, 'func1')() # 666 getattr(file, 'func2')() # 777
(2) hasattr
class A:name = 'tom'def __init__(self):self.age = 18 a = A()print(hasattr(A, 'name')) # True 判断A类是否含有name属性 print(hasattr(a, 'age')) # True 判断对象a是否含有age属性 print(hasattr(a,'sex')) # False
(3) setattr , delattr
class A:def __init__(self,name):self.name = namea = A('tom') setattr(a,'name', 'jack') # 把对象a的属性name的值改成'jack' print(a.name) # jack print(a.__dict__) # {'name': 'jack'} delattr(a,'name') # 删除对象a的name属性 print(a.__dict__) # {}
二. 内置方法
格式 : __名字__ 称呼 : 类中的特殊方法\内置方法 双下方法 魔术方法 (magic_method)
类中的每一个双下方法都有它自己的特殊意义 , 所有的双下方法没有需要你在外部直接调用的, 而是总有一些其他的内置函数特殊的语法来自动触发这些双下方法
1. __call__
功能 : 对象后面加括号,触发执行。即:对象() 或者 类()()
class A:DAY = 'MONDAY'def __call__(self):print('666')a = A() a() # 666 自动执行__call__方法 A()() # 666
2. __len__
class A:def __init__(self):self.lst = [1, 2, 3, 4, 5, 6, 7]def __len__(self):print(666)return len(self.lst)a = A() # 实例化对象 print(len(a)) # 7 len()自动执行__len__方法
3. __str__
class A:def __str__(self):return '%s %s %s %s %s' %(self.name, self.age, self.sex, self.height, self.weight)def __init__(self, name, age, sex, height, weight):self.name = nameself.age = ageself.sex = sexself.height = heightself.weight = weighta = A('jack', 18, '男', 55, 1.85) print(a) # print一个对象相当于调用一个对象的__str__方法 # jack 18 男 55 1.85 print(str(a)) # 内置的数据类型,内置的类,相当于执行__str__ # jack 18 男 55 1.85 print('1号: %s' %a) # 1号: jack 18 男 55 1.85
4. __new__
__new__ : 构造方法
在实例化之后,__init__之前先执行new来创建一块空间
class A:def __new__(cls, *args, **kwargs):obj = object.__new__(cls) # A类没有__new__,只能去找object里找print('第一步')return objdef __init__(self):print('第二步') a = A() # 先执行__new__方法,再执行__init__方法 # 第一步 # 第二步
单例类
# 单粒类 : 只能实现一个实例化对象空间的类 class A:__INSTANCE = Nonedef __new__(cls):if not cls.__INSTANCE :cls.__INSTANCE = object.__new__(cls)return cls.__INSTANCEdef __init__(self):passa1 = A() a2 = A() a3 = A() print(a1) # <__main__.A object at 0x000002096E378B38> print(a2) # None print(a3) # None
5. __repr__
class A:def __init__(self, name):self.name = namedef __repr__(self):return self.name a = A('jack') print(a) # jack 自动执行了__repr__方法
print()也会执行__str__方法,再把__str__加进程序看看
class A:def __init__(self, name):self.name = namedef __str__(self):return '执行str方法%s ' % self.namedef __repr__(self):return '执行repr方法%s ' % self.name a = A('jack') print(a) # 执行str方法jack print(str(a)+'\t' + repr(a)) # 执行str方法jack 执行repr方法jack print('%s*****%r' % (a, a)) # 执行str方法jack *****执行repr方法jack
__repr__ 和 __str__ 的区别与联系 :
__str__ : str(obj),要求必须实现了__str__,要求这个方法的返回值必须是字符串str类型 print , %s, str直接执行__str__ __repr__: 是__str__的备胎.如果有__str__方法,那么print %s str都先去执行__str__方法,并且使用__str__的返回值. 如果没有__str__, 那么 print %s str都会执行repr repr(obj),%r直接执行__repr__
# 子类没有__str__但是有__repr__,父类有__str__时 class A:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return self.age class B(A):def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return self.nameb = B('jack','18') print(b) # 18 先找本类的__str__ ,子类没有再找父类的__str__,父类没有再找子类的__repr__
在子类中使用__str__, 先找子类的__str__, 没有的话要向上找,只要父类不是object, 就执行父类的__str__, 但是如果出了object之外的父类都没有__str__方法,就执行子类的__repr__方法,如果子类也没有,还要向上继续找父类中的__repr__方法. 一直找不到 再执行object类中的__str__方法.6. __del__ : 析构方法
class A:def __init__(self, name):self.name = namedef __del__(self):print(666) a = A('jack') print(a.name) # jack del a.name # 666 删除对象a的name属性, 自动触发__del__方法,然后进行删除操作 # print(a.name) # 报错,对象a已经没有name属性
7. item系列
类的实例属性是字典的时候,使用以下三个方法:
class A:def __init__(self, name):self.name = namedef __getitem__(self, item):return getattr(self, item)def __setitem__(self, key, value):setattr(self, key, value)def __delitem__(self, key):delattr(self, key)a = A('jack') a['k'] = 'v' # 触发 __setitem__ print(a['k']) # 触发 __getitem__ del a['k'] # 触发 __delitem__class A:def __init__(self, lst):self.lst = lstdef __getitem__(self, item):print(self.lst[item])def __setitem__(self, key, value):self.lst[key] = valuedef __delitem__(self, key):self.lst.pop(key) a = A([0, 1, 2, 3, 4, 5]) a[3] # 3 a[1] = 'j' print(a.lst) # [0, 'j', 2, 3, 4, 5] del a[4] print(a.lst) # [0, 'j', 2, 3, 5]
8. __eq__ 定义等于操作符(==)的行为。
class A:def __init__(self, name):self.name = namedef __eq__(self, other):if self.name == other.name:return Trueelse:return False a1 = A('jack') a2= A('tom') a3 = A('jack')print(a1 == a2) # False == 自动触发__eq__ print(a1 == a3) # True
9. __hash__
# 对同一个值在多次执行python代码的时候hash值是不同 # 但是对同一个值 在同一次执行python代码的时候hash值永远不变print(hash('abc')) print(hash('abc')) print(hash('abc')) print(hash('abc')) # 第一次运行 # 6909065435967799450 # 6909065435967799450 # 6909065435967799450 # 6909065435967799450 # 第二次运行 # 4813272381834820912 # 4813272381834820912 # 4813272381834820912 # 4813272381834820912
字典的寻址和集合的去重都是通过hash算法完成的.
字典 : 通过哈希算法,把key值进行一次计算,算出哈希值,若是出现哈希值相同的key,则比较key值是否相同,若相同则覆盖value值,不同就二次寻址.
集合: 通过哈希算法,把元素的值进行一次计算,若是出现哈希值相同的元素,则比较元素值是否相同,若相同后面的则覆盖前面元素的值,不同就二次寻址.
# 一个类 # 对象的属性 : 姓名 性别 年龄 部门 # 员工管理系统 # 内部转岗 python开发 - go开发 # 姓名 性别 年龄 新的部门# 5个员工 # 如果几个员工对象的姓名和性别相同,这是一个人 # 请对这5个员工做去重
class Staff:def __init__(self, name, sex, age, partment):self.name = nameself.sex = sexself.age = ageself.partment = partmentdef __hash__(self):return hash(self.name + self.sex)# hash('%s%s'%(self.name,self.sex))# hash(self.name, self.sex) # 报错,因为给了两个值def __eq__(self, other):if self.name == other.name and self.sex == other.sex:return Trueelse:return Falses1 = Staff('jack', '男', 18, 'sales_department') s2 = Staff('tom', '男', 22, 'finace_departmrnt') s3 = Staff('vicky', '女', 20, 'marketing_department') s4 = Staff('jack', '男', 25, 'personnel_department') s5 = Staff('vicky', '女', 22, 'production_department') lst = [s1, s2, s3, s4, s5] print(lst) staff_set = set(lst) # 去重操作 print(staff_set) for person in staff_set:print(person.__dict__) # {'name': 'vicky', 'sex': '女', 'age': 20, 'partment': 'marketing_department'} # {'name': 'tom', 'sex': '男', 'age': 22, 'partment': 'finace_departmrnt'} # {'name': 'jack', 'sex': '男', 'age': 18, 'partment': 'sales_department'}
转载于:https://www.cnblogs.com/huangqihui/p/9393030.html
python面向对象 : 反射和内置方法相关推荐
- python全栈开发基础【第十七篇】面向对象反射和内置方法
一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静态方法:让类里的方法直接被 ...
- python 面向对象 类的内置方法
判断是不是类cls的对象 class A:passa = A() print(isinstance(a,A)) 判断类sub是不是super的子类 class A:passclass B(A):pas ...
- Python中常用的内置方法
Python中常用的内置方法: 比较大小.求和 如下所示: 代码块: #枚举:返回索引值和对应的value值for i,v in enumerate('westos'):print(i,v)#zips ...
- python中字典类型中的item是什么-python中 字典类型内置方法
python中 字典类型内置方法 一.字典(dict) 1·. 存多个值,但是每一个值都有一个key与之对应.列如存在值有姓名:jiayi.年龄:18.身高:173 2.定义方式 在{}内 ...
- Python入门学习-DAY27- isinstance与issubclass、反射、内置方法
isinstance与issubclass issubclass:判断子类是否属于父类,是则返回True,否则返回False isinstance:判断对象是否属于类,是则返回True,否则返回Fal ...
- Python之路(第二十七篇) 面向对象进阶:内置方法、描述符
一.__call__ 对象后面加括号,触发执行类下面的__call__方法. 创建对象时,对象 = 类名() :而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()( ...
- python 类调用不存在的方法_[python] 类常用的内置方法
内置方法 说明 __init__(self,...) 初始化对象,在创建新对象时调用 __del__(self) 释放对象,在对象被删除之前调用 __new__(cls,*args,**kwd) 实例 ...
- python 类的内置方法_【转】[python] 类常用的内置方法
原文:http://xukaizijian.blog.163.com/blog/static/170433119201111894228877/ 内置方法 说明 __init__(self,...) ...
- python字典内置方法_柳小白Python学习笔记 12 内置方法之字典方法
学习字典的时候只学习了最基本的字典定义和创建方式.今天再学习两种字典的创建方法及字典内置方法的使用. 现在春暖花开,所以我用花的元素创建了garden(花园)系列字典,字典的键是flowers(花名) ...
最新文章
- PHP基础——语法篇
- 二进制函数_SERVERLESS函数小解
- Linux环境下配置Tomat
- svn钩子程序上传文件中文文件导致报错的处理办法
- CompletableFuture异步调用
- oracle连接数一直超出,Oracle超出最大連接數問題及解決(…
- Oct 12: Patch Set Update Released
- [转载] Python基础:什么是字符串?字符串是用来做什么的?
- 安装magicdrawUML出现的问题
- Android上图片文字识别
- C++根据三个点坐标计算夹角
- 找出直系亲属 研究生机试 树
- doctrine-orm基础(单用doctrine避坑指南)
- VBA---打开excel
- 大一作业HTML网页作业:简单的旅游 1页 (旅游主题)
- 基于springmvc的Junit与Jmockit使用
- altera 设计--仿真--下载
- 潮人必备签名档,得闲就更新
- 2022 十大科技趋势!达摩院年终预测重磅出炉:AI for Science 高居榜首
- 系统资源监控-Windows自带资源监控
热门文章
- 关于路由器的配置参数
- 关于Vue中$nextTick的作用及实现原理(Vue进阶)
- 离职后工作居住证如何办理延期注销
- 抖音广告多少种,这些你知道吗?
- MYSQL登录遇到的问题:解决ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost:3306‘(10061)
- Linux jar包在screen开机自启
- 2016年最新版App内购买详细指南
- com 如何新打开ac
- 静态站点 免费_七个站点,您可以随意使用免费照片
- 在哪里计算机的cpu显卡硬盘,电脑硬件升级攻略 CPU/内存/显卡/固态硬盘该如何选择?...