反射

(1)反射的定义:

  反射就是通过字符串来操作python代码中的对象的属性和方法。

(2)为什么要用反射?三个场景:

  1.用户输入input

    从用户输入的字符串中,想转换为变量的名字。

  2.文件读取

    从文件中读出的字符串,想转换为变量的名字。

  3.网络


getattr()

  先看看getattr()的源码的解释:

def hasattr(*args, **kwargs): # real signature unknown"""Return whether the object has an attribute with the given name.This is done by calling getattr(obj, name) and catching AttributeError."""pass

getattr()源码解释

  具体使用:

  (1)getattr(obj,属性名)----> 传入字符串类型的属性名,返回属性的值,相当于执行了“obj.属性名”

  (2)getattr(obj,方法名)----> 传入字符串类型的方法名,返回对应方法的内存地址。

  谨记:如果第二个参数不存在的话,就会报错。

class A:name = 'he'age = 23
print(A.name)    #he
print(A.age)       #23#使用反射的形式,操作类的属性
print(getattr(A, 'name'))
>>>
he

#使用反射操作类中的方法
class A:number = 1def func(self):print('in the func')
a = A()
ret = getattr(a,'func')      #得到了func方法的内存地址
ret()                              #调用func()方法

hasattr()

def hasattr(*args, **kwargs): # real signature unknown"""Return whether the object has an attribute with the given name.This is done by calling getattr(obj, name) and catching AttributeError."""pass

hasattr的源码解释

  具体使用:

  hasattr(obj,字符串类型的属性名/方法名)--->判断对象中是否拥有指定属性/方法,返回True/False。

  谨记:所以hasattr经常和getattr一起使用,先用hasattr判断,再使用getattr取值。

#例子1:通过hasattr判断,再用getattr来取值。
class A:name = 'he'age = 23inp = input('>>>:')
if hasattr(A,inp):print(getattr(A,inp))
else:print('A类中没有对应的属性')>>>:name
he
>>>:sex
A类中没有对应的属性#例子2
class Student:def __init__(self,name,age):self.name = nameself.age = agedef show(self):for key in self.__dict__:                 #__dict__查看对象的所有属性print(key,self.__dict__[key])         # key self.__dict__[key]s = Student('he',23)
# s.show()if hasattr(s,'show'):func = getattr(s,'show')        #返回方法的内存地址,赋值给func()func()
>>>
name he
age 23

setattr()

def setattr(x, y, v): # real signature unknown; restored from __doc__"""Sets the named attribute on the given object to the specified value.setattr(x, 'y', v) is equivalent to ``x.y = v''"""pass

setattr的源码解释

  具体使用:

  setattr(obj,'name',value) ---->通过反射的方式为一个对象设置属性(增改操作),相当于obj.name=value

#正常情况下,想给对象设置一个值。
class Student:def __init__(self,name,age):self.name = nameself.age = agedef show(self):for key in self.__dict__:      #__dict__查看对象的所有属性print(key,self.__dict__[key]) # key self.__dict__[key]s = Student('he',23)
s.sex = 'male'
print(s.sex)
>>>
male#除了上面的方式之外,还有一种方式为对象设置属性,通过反射的形式.
setattr(s,'sex','male')
print(s.__dict__)
print(s.sex)
>>>
{'name': 'he', 'age': 23, 'sex': 'male'}

  除了给对象绑定属性,还给对象绑定一个函数。

#创建一个函数,通过setattr给对象绑上这个函数
class Student:def __init__(self,name,age):self.name = nameself.age = agedef show(self):for key in self.__dict__:         #__dict__查看对象的所有属性print(key,self.__dict__[key]) # key self.__dict__[key]s = Student('he',23)
def func1(a,b):print(a,b)
setattr(s,'func',func1)       #把普通函数当做函数添加到对象空间中
s.func(1,2)
print(s.__dict__)
>>>:
1 2
{'name': 'he', 'age': 23, 'func': <function func1 at 0x000001F16D252F28>}

delattr()

  delattr(obj,'name'):通过反射的方式,删除对象中的属性(删除操作)

class Student:def __init__(self,name,age):self.name = nameself.age = agedef show(self):for key in self.__dict__:      #__dict__查看对象的所有属性print(key,self.__dict__[key]) # key self.__dict__[key]s = Student('he',23)
#正常方法
del s.age
print(s.__dict__)#通过delattr反射的方式
delattr(s,'age')
print(s.__dict__)

  总结:

  (1)hasattr():判断一个对象中是否能够调用一个名字,返回True/False

  (2)getattr():返回一个对象中的名字的值

  (3)setattr():为一个对象设置属性(增加/修改操作)

  (4)delattr():删除一个对象的某个属性(删除操作)


通过反射来操作模块

  通过上面学习的反射的四种方法,我们知道了如果通过反射来操作类中的属性/方法,但是除了"类名.属性名/方法名","对象名.属性名/方法名"之外,我们还接触过“模块名.函数名()”,那么能否通过反射来操作模块呢?答案是肯定的。

  在python中,一切皆对象,当导入一个模块时,模块其实就可以看成一个对象。

  getattr(模块,'属性名/方法名')

import sys
print(getattr(sys, 'path'))
>>>
C:\Python36\python.exe E:/python_training_s1/day21/day21_training.py
['E:\\python_training_s1\\day21', 'E:\\python_training_s1', 'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib', 'C:\\Python36', 'C:\\Users\\hesihao\\AppData\\Roaming\\Python\\Python36\\site-packages', 'C:\\Python36\\lib\\site-packages', 'D:\\pycharm\\PyCharm 2018.1.4\\helpers\\pycharm_matplotlib_backend']

通过反射来操作当前文件

  既然反射能够操作模块,那么当前文件其实也是一个模块,通过sys.modules可以看出,当前文件就是sys.modules['__main__']。

# 方式一:sys.modules[__main__]
import sys
name = 'he'
def foo():print('这是本模块的函数foo')print(getattr(sys.modules['__main__'], 'name'))
getattr(sys.modules['__main__'], 'foo')()
>>>
he
这是本模块的函数foo

  通过sys.modules['__main__']好像完成了要求,但是,仔细想一下,使用__main__表示当前文件,假如在另外一个py文件中把当前文件导入,此时__main__便指向的是另外一个py文件,使用sys.modules['__main__']这种方式显然是不妥的,那么要怎么解决?

  使用sys.modules[__name__]就能完美解决,因为__name__就是'__main__'。

#通过sys.modules[__name__]反射当前模块import sys
name = 'he'
def foo():print('这是本模块的函数foo')
getattr(sys.modules[__name__],'foo')()
>>>
这是本模块的函数foo

  总结:

  sys.modules['__main__'] : __main__会随着文件的不同而不同,存在安全隐患。

  sys.modules[__name__]:__name__不管在哪里导入这个模块,都代表这个文件。

如何反射来操作当前模块中的类

import sys
class Student:def __init__(self,name,age):self.name = nameself.age = agedef show(self):for key in self.__dict__:      #__dict__查看对象的所有属性print(key,self.__dict__[key]) # key self.__dict__[key]main = sys.modules[__name__]
cls = getattr(main,'Student')
he = cls('小何',23)

  

转载于:https://www.cnblogs.com/hebbhao/p/9594263.html

DAY21 反射(hasattr,getattr,setattr,delattr)相关推荐

  1. python3 hasattr getattr setattr delattr 对象属性 反射

    hasattr()函数 hasattr()函数用于判断是否包含对应的属性 语法: hasattr(object,name) 参数: object--对象 name--字符串,属性名 返回值: 如果对象 ...

  2. Python中dir,hasattr,getattr,setattr,vars的使用

    Python中dir,hasattr,getattr,setattr,vars的使用 Python一切皆对象,对象都有很多属性和方法,使用时我们怎么知道对象有哪些属性,以及如何获取对象的属性和设置对象 ...

  3. Python的hasattr() getattr() setattr() 函数使用方法详解

    Python的hasattr() getattr() setattr() 函数使用方法详解 (一) hasattr(object,name) 函数 判断一个对象里面是否有 name 属性或者 name ...

  4. python中setattr用法_详解Python的hasattr() getattr() setattr() 函数使用方法

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

  5. python getattr setattr_python hasattr/getattr/setattr介绍

    摘要 Python 对应属性和方法的判断 hasattr/getattr/setattr hasattr 判断一个对象里面是否有name属性或者方法,返回值为Boolean值, 有name 返回tru ...

  6. python hasattr函数_Python的反射机制、hasattr() getattr() setattr() 函数使用方法详解

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

  7. Python基础教程:hasattr() getattr() setattr() 使用方法详解

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

  8. Python中hasattr() getattr() setattr() 函数的使用

    hasattr(object,name)函数: 判断一个对象里面是否有name属性或者name方法,返回bool值,有name属性(方法)返回True,否则返回False. class functio ...

  9. Python hasattr() getattr() setattr() 函数使用

    1.setattr(object, name, values) 给对象设置属性,如果对象不存在,则创建对象 layers = nn.Sequential(nn.Conv2d(curr_dim, cur ...

  10. [转载] python hasattr函数_Python的hasattr() getattr() setattr() 函数使用方法详解

    参考链接: Python hasattr() hasattr(object, name) 判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回Fa ...

最新文章

  1. Git本地与远程配对命令:两种 一种是在推送push时候配对 一种是新建分支checkout -b时候配对
  2. ASP.NET MVC3 权限验证
  3. Pow(x, n)Python解法
  4. SQL分组取每组前一(或几)条记录(排名)
  5. readyState属性和status属性
  6. 睡眠多少分钟一个循环_睡眠分为几个阶段每个阶段大概多少时间?
  7. mysql空间数据类型的使用_MYSQL 空间数据类型用法
  8. mac java连通r_MacOS安装rJava
  9. linux上sh工具如何使用,怎样用 Bash 编程:语法和工具 | Linux 中国
  10. 查看计算机GUID的WMI类
  11. python2升级python3
  12. ASP.net 中 OutputCache 指令各个参数的作用。
  13. segger公司调试cortex-m内核出现hardfault的方法
  14. Heartbeat高可用软件服务--1.Heartbeat介绍(2)
  15. C-7统计元音字母个数
  16. c++语言如何判断奇偶数,C++ 判断奇数偶数
  17. 恢复云数据库MySQL的备份文件到自建数据库总结
  18. 柔性电子:超薄可延伸Ag-In-Ga电子皮肤,用于生物电子和人机交互
  19. ps3存档是php文件,PS3存档使用方法教程
  20. 【ZJOI2017】仙人掌 题解

热门文章

  1. 【排序算法复习备忘】冒泡、选择、插入、归并、快排、堆排序
  2. C陷阱与缺陷阅读笔记(下)
  3. js怎么函数怎么给另一个函数传值并且不调用_2020年最火爆的Vue.js面试题
  4. Kafka自动提交offset设置
  5. 开启 C++ 生活 -- 第一个 C++ 程序
  6. JS学习--Math对象
  7. [译]Flask教程--Cookie
  8. Openfire服务端安装和配置
  9. Windows 8 Metro中文件的操作及访问(读写删除复制)
  10. 解决RPM包依赖的几种方法