首页 > 代码库 > 反射、定制数据类型

反射、定制数据类型

isinstance,issubclass
isinstance(obj,cls) ,检查obj是否是类cls的对象
 
class Foo(object):
    pass

obj = Foo()
print(isinstance(obj,Foo))

issubclass(sub,super)检查sub类是否是super类的派生类
class Foo:
    pass
class sub(Foo):
    pass

print(issubclass(sub,Foo))

反射:getattr,setattr,delattr,hasattr
hasattr:查看对象中是否有此字符串属性,返回Ture或False
class Foo:
    def __init__(self,name):
        self.name = name

f = Foo(Mitsui)
print(hasattr(f,name))

getattr:查看对象是否有此属性,返回属性的值。
class Foo:
    country = China
    def __init__(self,name):
        self.name = name

f = Foo(Mitsui)
res = getattr(f,name)
res1 = getattr(f,country)
print(res1,res)


setattr:setattr(obj,str,value)设置对象的属性
setattr(f,age,18)
print(f.__dict__)
print(f.age)

delattr:delattr(obj,str)删除对象的属性
delattr(f,name)
print(f.__dict__)
print(f.name)
>>>:
{age: 18} print(f.name) AttributeError: Foo object has no attribute name


一切皆对象,类也是对象,也可以调用以上的方法。
当前位置导入由当前文件转换的模块:
import sys
this_module = sys.modules[__name__]

基于这些反射方法,可以实现代码可插拔机制:
在代码合作编写阶段,一方不需等另一方的编写完成,只需了解他所具备的属性功能便可自行编写自己的代码,
这样可以确保自己不受他人的影响。比如下面这一段代码:
技术分享
Client端:
class FtpClient:
    ftp客户端,但是还没有实现具体的功能
    def __init__(self,addr):
        print(正在连接服务器[%s]% addr)
        self.addr = addr

Server端:
from FtpClient import FtpClient
f1 = FtpClient(192.168.1.1)
if hasattr(f1,get):
    func_get = getattr(f1,get)
    func_get()
else:
    print(----->还未存在此方法)
    print(先处理其它逻辑)
执行结果:
>>>>:
正在连接服务器[192.168.1.1]
----->还未存在此方法
先处理其它逻辑
View Code
当client端get方法还未编写,不影响server端代码的运行,而当Client端编写好get方法
此时运行Server端会根据代码做出相应的变动
技术分享
class FtpClient:
    ftp客户端,但是还没有实现具体的功能
    def __init__(self,addr):
        print(正在连接服务器[%s]% addr)
        self.addr = addr
    def get(self):
        print(get正在运行)

>>>>:
正在连接服务器[192.168.1.1]
get正在运行
View Code

通过字符串导入模块:
m = input(输入你要导入的模块)
m1 = __import__(m)(不建议)   == m1 = importtlib.import_module(m)(官方建议方法)

内置attr:__getattr__,__setattr__,__delattr__
__getattr__:当对象执行不存在的属性时,会触发__getattr__
技术分享
class Foo:
    def __init__(self,name):
        self.name = name
    def __getattr__(self, item):
        print(__getattr__已触发)

f1 = Foo(Mitsui)
print(f1.name)
print(f1.names)
>>>>:
Mitsui
__getattr__已触发
None            #有返回值默认是None
View Code

 

 

反射、定制数据类型