python反射和高阶内置方法
1.isinstance:判断对象和类的关系
#判断结果返回bool类型
class A:pass
class B(A):pass
a = A()
print(isinstance(a,A)) #True isinstance(对象,类)
2.issubclass:判断子类和父类的关系
#判断结果返回bool类型
class A:pass
class B(A):pass
a = A()
print(issubclass(B,A)) #True issubclass(子类,父类)
3.反射
是用字符串类型的名字,去操作变量
反射对象中的属性和方法:
- hasattr
- getattr
- setattr
- delattr
3.1 getattr(重要)
反射对象的属性 —getattr(对象,属性)
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:
def func(self):
print('in func')
a = A()
a.name = 'liyanan'
a.age = 18
# 反射对象的属性 --getattr(对象,属性)
ret = getattr(a,'name') # 通过变量名的字符串形式取到的值
print(ret)
user = input('>>>>')
print(getattr(a,user)) #假如输入name,则执行a.name
反射对象的方法 —getattr(对象,方法)
#接上
# 反射对象的方法
ret = getattr(a,'func') #getattr(a,'func') == a.func
ret()
反射类的属性
class A:
price = 20
def func(self):
print('in func')
# 反射类的属性
# A.price
print(getattr(A,'price'))
反射类的方法
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:
price = 20
@classmethod
def func(self):
print('in func')
# 反射类的方法:classmethod staticmethod
# A.func()
if hasattr(A,'func'): #判断类中是否存在第二个参数的方法
getattr(A,'func')() #如果有就执行
反射模块的属性
import my # my为自己写的其他模块
#反射模块的属性 my.day为模块的属性
print(getattr(my,'day'))
反射模块的方法
#反射模块的方法
getattr(my,'func')()
内置模块也能用反射
反射自己模块中的变量和函数
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import sys
# print(sys.modules['__main__'])
year = 2019
def login():
print('welcome')
#反射自己模块中的变量
print(getattr(sys.modules[__name__],'year'))
user_in = input('>>>')
print(getattr(sys.modules[__name__],user_in))
#反射自己模块中的函数
getattr(sys.modules[__name__],'login')()
3.2 hasattr
与getattr配合使用,主要做判断
注意参数要跟getattr保持一致
import sys
year = 2019
if hasattr(sys.modules[__name__],'year'):
print(getattr(sys.modules[__name__],'year'))
3.3 setattr(了解)
设置修改变量
setattr(对象,‘要修改的属性’,‘修改的内容’)
class A:
pass
a = A()
setattr(a,'name','nezha')
setattr(A,'name','taibaijinxing')
print(a.name) #打印nezha
print(A.name) #打印taibaijinxing
3.4 delattr(了解)
删除一个变量
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:
pass
a = A()
setattr(a,'name','nezha')
setattr(A,'name','taibaijinxing')
delattr(a,'name')
print(a.name) #打印taibaijinxing,因为实例化对象调用了父类的name属性
delattr(A,'name')
print(a.name) #报错,没有name属性
4.高阶内置方法
__del__
方法:析构函数:在删除一个对象之前,进行的一些收尾工作
class A:
def __del__(self): #析构函数:在删除一个对象之前进行一些收尾工作
self.f.close()
a = A()
a.f = open('db.txt','r',encoding='utf-8') # 打开文件,拿到了文件操作句柄
del a #del既执行了这个方法,又删除了变量
__call__
方法:实例化后的对象加括号,相当于默认执行了此方法
class A:
def __init__(self,name):
self.name = name
def __call__(self, *args, **kwargs):
for k in self.__dict__:
print(k,self.__dict__[k])
a = A('liyanan')() #实例化对象后加括号相当于执行了内部的__call__方法
#a() 结果为打印self.__dict__中的静态属性 name liyanan
item方法
- getitem
- setitem
- delitem
- 附加的delattr
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Foo:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
#getitem方法
def __getitem__(self, item):
if hasattr(self,item): #判断item是否存在/传值
return self.__dict__[item]
#setitem方法
def __setitem__(self, key, value):
self.__dict__[key] = value
#delitem方法
def __delitem__(self, key):
del self.__dict__[key]
#delattr方法
def __delattr__(self, item):
print('del obj.key时,我执行')
self.__dict__.pop(item)
f = Foo('alec','18','男')
print(f['name']) #f['']这种格式默认执行了类中的__getitem__方法,等于f.name
f['hobby'] = 'python' #默认调用了setitem方法,使类中的字典添加了key和value
print(f.hobby,f['hobby']) #结果都为python
del f.hobby #先调用类中的delattr方法,如果没有就调用object中的(直接删除)
del f['hobby'] #默认调用了delitem方法,删除了类中的静态属性
__new__
用法(面试会考)
所有的类中都是先执行__new__
方法,再执行__init__
方法
使用场景:设计模式:单例模式:只能有一个实例化对象,后面实例化的对象属性都会覆盖第一个对象的属性,如果没有覆盖则用第一个对象的属性
#单例模式
class A:
__instance = False #设置一个私有属性
def __init__(self,name,age):
self.name = name
self.age = age
def __new__(cls, *args, **kw): #先执行new,再执行__init__方法
if cls.__instance:
return cls.__instance
cls.__instance = object.__new__(cls)
return cls.__instance
yanan = A('yanan',26)
yanan.cloth = 'cool'
beijing = A('beijing',23)
print(yanan) #<__main__.A object at 0x000001B336D38C50>
print(beijing) #<__main__.A object at 0x000001B336D38C50> 一样的内存地址,证明只能实例化一个对象
print(yanan.name) #beijing 被第二次实例化对象<北京>给覆盖了
print(beijing.name) #beijing
print(beijing.cloth) #cool 第二次实例化对象<北京>没有覆盖,则用第一个对象的属性
__eq__
方法
用法:比较实例化后的对象属性是否相等
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:
def __init__(self,name):
self.name = name
#eq方法
def __eq__(self, other):
if self.__dict__ == other.__dict__:
return True
else:
return False
ob1 = A('pig')
ob2 = A('pig')
print(ob1 == ob2) #True
__hash__
方法
hash()是系统的哈希用法,以对象的内存地址进行哈希的
__hash__
可以自己控制哈希用法
class A:
def __init__(self,name,sex):
self.name = name
self.sex = sex
def __hash__(self):
return hash(self.name+self.sex)
a = A('agg','公')
b = A('agg','公')
print(hash(a))
print(hash(b))
#系统的哈希用法是根据内存地址处理的
#此类中的自己写的哈希算法是根据值来处理的
示例:
实例化对象去重
class A:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:
return True
return False
def __hash__(self):
return hash(self.name + self.sex)
a = A('agg','公',5)
b = A('agg','公',5)
print(hash(a))
print(hash(b))
print(set((a,b))) #去重,去除重复的实例化对象(只去重name和sex)