反射以及部分内置方法

issubclass() 以及instance() 用法

issubclass() #判断第一个类是不是第二个类的子类,返回true或者false

class Foo:
    pass
class Bar(Foo):
    pass
class Tt(Bar):
    pass
print(Bar.__bases__)
print(issubclass(Bar,Foo))
print(issubclass(Tt,object))
#
(<class '__main__.Foo'>,)
True
True

isinstance() 判断第一个参数是不是第二个参数的对象,返回true或者false

class Foo:
    pass
class Tt():
    pass
f=Foo()
print(isinstance(f,Foo))
print(isinstance(f,Tt))
#
True
False

反射

1.反射就是通过字符串操作来操作字符串的相关属性,主要以下四个函数

getattr() # 获取对象中的属性或方法

import os
print(getattr(os,'path'))
<module 'ntpath' from 'F:\python\lib\ntpath.py'>

hasattr() #判断对象中是否有该属性或者方法(属性或方法用字符串表示)

import os
print(hasattr(os,'path'))   #判断了模块Os模块中有没有属性·path
#  True

delatter() #删除对象中的属性和方法

class AS :
    pass
a=AS()
setattr(a,'age','wwb')
print(a.age)   # 表示添加成功wwb
print(a.__dict__)    #{'age': 'wwb'}
delattr(a,'age')
# print(a.age)    
print(hasattr(a,'age'))   # False  判断是age

setattr() # 向对象中设置属性和方法

class AS :
    pass
a=AS()
setattr(a,'age','wwb')
print(a.age)
print(a.__dict__)

应用:利用反射查找该模块是否存在某个方法

"""
 5 程序目录:
 6     module_test.py
 7     index.py
 8  
 9 当前文件:
10     index.py
11 """
import module_test as obj 
#obj.test() 
print(hasattr(obj,'test')) 
getattr(obj,'test')()

2.反射的好处

可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

# 我以为它写完了
utils.eat()    # 这样获取该对象的方法,但是获取不到的话会报错
# 更安全
if hasattr(utils,'eat'):
    eat=getattr(utils,'eat')
    eat()
else:
    print('那个人还没写完呢')     # 这样先判断有没有,有了在获取,没有的话输出,这样更保险程序不会报错

内置方法(魔法方法)

1.__str__:如果不重写__str__ print打印会打印出内存地址#如果重写了,会打印出你想要的,也就是程序本来写好这个方法的,当你打印调用的话就会打印出本来写好的,就像内存地址

# 不重写内置方法的情况下
class Foo:
    def __init__(self,name):
        self.name=name
f=Foo('wwb')
print(f)       # 相当于print(f.__str__())
#
# _main__.Foo object at 0x000001E4E51FDA58>
# 重写的情况下
class Foo:
    def __init__(self,name):
        self.name=name
    def __str__(self):
        return '['+self.name+']'
f=Foo('wwb')
print(f)       # 相当于print(f.__str__())
#
#[nick]
l=[1,2,3]
# #本质也是调用list的__str__方法
print(l)
[1, 2, 3]

2.__repr__ 跟str类似,在交互式命令下直接写变量名,会执行__repr__

3.__setattr__,__delattr__,__getattr__(重要)

**点拦截方法

​ 如果去对象中取属性,一旦取不到,会进入到__getattr__ (如果没有找到)**

class Foo:
    def __init__(self,name):
        self.name=name
    def __getattr__(self, item):  #
        print('xxxx')
        return '你傻逼啊,没有这个字段'
f=Foo('wwb')
print(f.name)
print(f.age)
print(f.__dict__)
#
wwb
xxxx
你傻逼啊,没有这个字段
{'name': 'wwb'}

​ 如果去对象中赋值属性,一旦取不到,会进入到__setattr__

class Foo:
    def __init__(self,name):
        self.name=name
    def __setattr__(self, key, value):
        print('yyyyy')
f=Foo('wwb')    # 赋值,在这个过程中会触发__setattr__ 
print(f.__dict__)  # 因为没有触发系统的__setattr__,所以没有赋值成功
#
yyyyy
{}

​ 如果删除对象中的属性,会进入__delattr__

class Foo:
    def __init__(self,name):
        self.name=name
    def __delattr__(self, item):
        print('zzzzz') 
f=Foo('wwb')   
del f.name
print(f.__dict__)     # 因为没有进入系统的__delattr__,所以没有删除成功
#
zzzzz
{'name': 'wwb'}
原文地址:https://www.cnblogs.com/wwbplus/p/11454200.html