博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面向对象进阶----->反射 getattr 和hasattr方法
阅读量:6393 次
发布时间:2019-06-23

本文共 6679 字,大约阅读时间需要 22 分钟。

判断一个对象有没有血缘关系:isinstance() 里面写的是字类对象和父类名用来判断他们的关系

issubclass()是用来判断两个类是不是有继承的关系 ,括号内 写字类名和父类名  可以判断出字类和父类或者爷爷类的关系

 
class A:     role = "Person"     def __init__(self):         self.money = 500     def func(self):         print("*"*10) a = A() print(a.func) #得到是内存地址 # print(a.func()) getattr(a,'func')() print(getattr(a, 'money'))
class Foo(object):    def __init__(self , name):        self.name = nameclass Doo(Foo):    def __init__(self,name, age):        super().__init__(name)        self.age = agef = Foo('alex')d = Doo('laowang ',14)class B:passclass  A(B):passa = A()print(isinstance(a,A))print(isinstance(a,B))  #isinstance 判断一个对象和一个类有没有血缘关系isinstance()class C:passclass D(C):passprint(issubclass(C,D))print(issubclass(D,C))

反射的4个内置函数
getattr() ******
hasattr() ******
strattr() 修改和新建
delattr() 删除一个属性

反射是;使用字符串数据类型的变量名来使用变量

hasattr()  判断一个命名空间中有没有这个名字 getattr()从命令空间内获取这个名字对应的值 从命令空间中获取这个名字的值

hasattr(object, name)

判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False。
需要注意的是name要用括号括起来

getattr(object, name[,default])

获取对象object的属性或者方法,如果存在打印出来,如果不存在就报错,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号。

class A:    role = 'Person'print(getattr(A,'role'))  使用字符串数据类型的变量 访问一个命名空间中的名字class  B:    l = '你好'    def func(self):        print(111)print(getattr(B,'l'))getattr(B,'func')(1)   #从类中找方法找的是它的内存地址 你需要加上括号才能调用它 并且传参 self找一个属性 直接就可以找到这个属性的值找一个方法找到的就是这个方法的内存地址你可以对这个内存地址进行赋值来及逆行调用getattr(B,'func')(3)print(hasattr(B,'l'))print(hasattr(B, 'v'))ret = input('>>>')if hasattr(B , ret):    print(getattr(B, ret))hasattr()  判断一个命名空间中有没有这个名字getattr()从命令空间内获取这个名字对应的值从命令空间中获取这个名字的值

其实eval类似getattr()方法 可以直接取值  但是一般除了取文件中的内容是不能用eval的  是防止一些错乱所以这个时候就有了反射getattr()方法

不论 hasattr()还是getattr()你所查询判断的内容必须是字符串类型的就是用引号括起来的 就好比你从文件中取出文件但是你的文件是什么类型的呢 是str的 所以需要用引号括起来

hasattr是用来判断  getattr使用来获取的  getattr()来获取的内容是方法的时候必须在最后加上括号括号括号(重要的说三遍)不然会不执行 因为方法执行必须加括号,调用的时候是对象的时候括号内不需要传递参数,如果是类的时候就不需要传递参数

class A:    role = 'Person'    def func(self):        print('*'*self)a = A()print(hasattr(a,'func'))if hasattr(a,'func'):    getattr(A, 'func')(3)if hasattr(A,'func') :    getattr(a,'func')(5)import osgetattr(os,rename)(old, new)a = 1b = 2def login():    print('执行了login')def register():    print('执行了register方法')import sys# sys.modules['__main__'],func = input('>>').strip()getattr(sys.modules['__main__'],func)()class  A:    def b(self):        print(111)a = A()fun = input('>>').strip()if hasattr(a,'func'):    getattr(a,'func')(1)else :    print(2)class A:    def __init__(self, name, age, sex, cls):        self.name = name        self.age = age        self.sex = sex        self.cls = cls    def __len__(self):        return 5a = A('a',33, 'nv', 2)print(len(a))class D:    role = '你好'    def func(self):        print(111)d = D()# print(hasattr(d,'role'))info = input('》》').strip()if hasattr(d,info):  #hasattr用来判断你的内容是不是存储的有这个变量   getattr(D,'func')(1)class B:passclass A(B):passa = A()print(isinstance(a,A))print(isinstance(a,B))  #检测到继承的关系print(isinstance(A,B))  #只能用字类对下个和父类名来判断print(type(a)is A) #type只能狗单纯的判断类print(type(a) is B)判断一个类和另外一个类有没有血缘关系isinstance()class B:passclass C(B):passclass D(C) :passprint(issubclass(C,D))print(issubclass(D,C))  #issubclass判断是不是继承# isinstance()只可以用字类对象和父类名来判断 ,因为判断是不是有血缘关系print(issubclass(B,C))  #继承和被继承者不能颠倒class  A:    role = 'ni'    def func(self):        print(666)a = A()info = input('>>').strip()if hasattr(a,info):    getattr(a,info)()  #通过对象是不用传递参数的  但是通过类 是需要传递参数的def login():    print('执行了login方法')def register():    print('执行了注册功能')import sysfunc = input('>>').strip()if hasattr(sys.modules['__main__'],func):    getattr(sys.modules['__main__'], func)()def login():    print('您在执行login的操作')def register():    print('您在执行reguster的操作')import sys# print(sys.modules['__main__'])func = input('》》').strip()if hasattr(sys.modules['__main__'], func):    getattr(sys.modules['__main__'],func)()import time# time.time()print(getattr(time,'time')())role = 123print(eval('role'))  #但是这个eval除了是去除文件中的信息的时候用到 其他的时候一般是禁止使用的class A:    role = 'Person'    def func(self):        print('*'*self)ret = input('>>').strip()# print(A.__dict__[ret])  #打印你所输入的类的属性的对应的值 因为你的内容是以字典的形式存储起来的  那么就用__dict__来查看print(getattr(A,ret))  #从a的命名空间里找一个属性 直接就可以找到这个属性的值print(getattr(A,'role'))f = getattr(A, 'func');f(10)  #也可以这样的简写  从A的命名空间里找一个方法 招待的就是这个方法的内存地址值A.func(1)反射you正常情况下如果可以拿到这个变量 那么如果有有这个变量的字符串形式 就是可以用反射获取到这个值使用字符串类型的变量名 访问一个命名空间中的名字找一个属性 直接就可以找到这个属性的值找到一个方法直接找到的是这个方法的内存的地址就是你找不论变量还是方法必须是通过字符串类型的来查找 因为你存储文件也是以字符串类型的形式来查找 所以你直接用getattr来查找必须加引号hasattr() 判断这个空间内有没有这个名字getattr从命名空间中获取这个名字对应的值类的反射就是 类可以获取类中的属性和方法class  A:    role  = 'Perosn'    def func(self):        print('*'*self)a = A()# print(getattr(a, role))  #你需要以字符串的 类型来查找不然找不到会报错,因为就好比你文件的内容也是以字符串的类型存储的if hasattr(a,'func'):    getattr(A,'func')(10)getattr()
View Code

 

用getattr验证对象是不是含有这个方法 那么不需要传递参数 但是类名验证需要传递参数

#第一种验证对象中含有这个方法class A:    def b(self):        print(111)a = A()func = input('>>').strip()if hasattr(a,func):  # 验证对象中是否有这个    getattr(a,func)()  # 因为是对象名验证的所以不需要传递参数else:    print(333)#下面验证对象是否含有class A:    def b(self):        print(111)a = A()func = input('>>').strip()# if hasattr(A, func):#     getattr(A,func)()  #不传递参数直接会报错 缺少self参数if hasattr(A, func):    getattr(A, func)(a) #如果没有特殊规定这个参数可以随意传递else :    print(333)

 

类使用类命名空间中的名字
getattr(类名,'名字')
对象使用对象能用的方法和属性
getattr(对象名, '名字')
模块使用模块中的名字
导入模块
getattr(模块名, '名字')

 用getattr查看当前位置下的内容地址: (找到地址我们可以根据地址做很多有意义的事)

import sysdef bb():    print(666)func = input('>>').strip()if hasattr(sys.modules['__main__'], func):  #判读当前位置中是否有func的内容  sys.modules['__main__']是显示当前位置    getattr(sys.modules['__main__'],func)()  # 找到位置后根据这个位置来查找这个地址下的方法或者属性  这个事查找方法 别忘了加()

 

 

也可以获取模块中内容

def login():    print('执行login功能')def register():    print('执行register功能')import sys  # 和python解释器相关的内容都在sys里print(sys.modules['__main__'])func = input('>>>')if hasattr(sys.modules['__main__'],func):    getattr(sys.modules['__main__'],func)()
import time time.time() print(getattr(time, 'time')())
import os os.rename('old','new') getattr(os,'rename')('old','new')  #获取os.rename的功能

 

 

 

 

内置函数__len__和内置方法len()是唯一对应的关系  

就是__len_-中的内容都可以通过len来得到 不论任何值 这个时候如果len得到的是__len__中的内容就不是求长度了

class A:    def __init__(self, name, age, sex, cls):        self.name = name        self.age = age        self.sex = sex        self.cls = cls    def __len__(self):        # return len(self.__dict__)        return 111a1 = A('alex', 81, '不详', 2)print(len(a1))  #这个时候就不是得到长度了而是类中的__len__中的返回值

内置的东西

# 都和内置的方法有着千丝万缕的联系

 

# 字典的存储

# hash

 

class A:

def __init__(self,name,age,sex,cls):
self.name = name
self.age = age
self.sex = sex
self.cls = cls
def __hash__(self):
return 0
a1 = A('alex',81,'不详',2)
print(hash(a1))

 

 

转载于:https://www.cnblogs.com/zhaoyunlong/p/8876637.html

你可能感兴趣的文章
MongoDB学习笔记(查询)
查看>>
freemarker自定义标签的写法和使用
查看>>
使用Gitlab CI进行持续集成
查看>>
Win32编程基本概念
查看>>
×××灯式样的站点链接说明,链接提示
查看>>
Linux下动态IP和静态IP的设置方法
查看>>
SUSE配置网关
查看>>
java中获取字母和数字的组合
查看>>
8-3 泛型
查看>>
你是“职业”软件开发吗?——书评《浮现式设计-专业软件开发的演进本质》...
查看>>
iOS 多线程 之 GCD(大中枢派发)(二)
查看>>
开源项目 log4android 使用方式详解
查看>>
ssh命令详解
查看>>
C# 中字符串转换成日期
查看>>
垃圾短信相关用户细分方案
查看>>
免费的Windows系统工具
查看>>
脚本:将git项目下载到本地并启动
查看>>
Linked List Cycle && Linked List Cycle II
查看>>
SeleniumTest
查看>>
ubuntu10.04 交叉编译 aria2 总结
查看>>