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()

反射类的属性

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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(对象,‘要修改的属性’,‘修改的内容’)

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:
    pass

a = A()
setattr(a,'name','nezha')
setattr(A,'name','taibaijinxing')
print(a.name)           #打印nezha
print(A.name)           #打印taibaijinxing

3.4 delattr(了解)

删除一个变量

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__方法:析构函数:在删除一个对象之前,进行的一些收尾工作

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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)

猜你喜欢

转载自blog.csdn.net/sinat_38682860/article/details/108996085
今日推荐