反射

通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

    1、getattr(object, name[, default]) -> value

Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.

判断类中是否有指定的方法,如下:

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self):
print("%s is eating......" %self.name) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
print(hasattr(d,choice))
运行如下:
>>:talk
False
>>:eat
True

我们知道,有时候我们要根据用户输入来判断类中是否有某种方法,这样我们就能执行了。如何去判断呢?可以使用hasattr(object,name)方法。上面,我们实现了动态判断方法,如果存在返回True,否则返回False。

    2、getattr(object, name[, default]) -> value
    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self):
print("%s is eating......" %self.name) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
print(getattr(d,choice))
运行结果如下:
>>:tall
Traceback (most recent call last):
  File "/home/zhuzhu/第七天/get_attr.py", line 11, in <module>
    print(getattr(d,choice))
AttributeError: 'Dog' object has no attribute 'tall'
>>:eat
<bound method Dog.eat of <__main__.Dog object at 0x7fecf92428d0>>

从上面可以看出,getattr()是获取属性的内存地址,如果存在返回内存地址,如果不存在,则返回错误,提示类中不存在这个方法。

既然getattr()存在放回方法的内存地址,那么加上括号执行一下,如下:

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self):
print("%s is eating......" %self.name) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
getattr(d,choice)()
运行结果如下:
>>:eat
alex is eating......

从上面可以看出,程序正常执行了,通过上面,我们可以发现,hasattr()和getattr()经常结合一起使用,hasattr()判断是否有这个方法,而getattr()用来执行。如果存在,则调用getattr()进行执行。如下:

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self):
print("%s is eating......" %self.name) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
if hasattr(d,choice):
'''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
getattr(d,choice)() else:
print("您输入的方法不存在,请核对后重新输入:")
运行结果如下:
>>:eat #存在执行方法
alex is eating......
>>:tall #不存在,提示方法没有
您输入的方法不存在,请核对后重新输入

从上面代码可以看出,能够实现动态用户输入判断方法是否存在,存在执行,不存在提示的功能。

下面是实现带参数的情况:

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self,food):
print("%s is eating......%s" %(self.name,food)) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
if hasattr(d,choice):
'''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
func = getattr(d,choice)
func("chenronghua")
#getattr(d,choice)("chenronghua") else:
print("您输入的方法不存在,请核对后重新输入:")
运行结果如下:
>>:eat
alex is eating......chenronghua

   也可以判断属性是否存在,如下,就判断里面单纯的属性,得到属性值:

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self,food):
print("%s is eating......%s" %(self.name,food)) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
if hasattr(d,choice):
'''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
func = getattr(d,choice)
print(func)
# func("chenronghua")
#getattr(d,choice)("chenronghua") else:
print("您输入的方法不存在,请核对后重新输入:")
运行结果如下:
>>:name
alex

    3.setattr(obj, name, value, /)
    Sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
    添加动态属性:

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self,food):
print("%s is eating......%s" %(self.name,food)) def talk(self):
print("%s is talking....." %self.name) def laugh(self):
print("%s is laughing....." %self) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
if hasattr(d,choice):
'''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
func = getattr(d,choice)
print(func)
# func("chenronghua")
#getattr(d,choice)("chenronghua") else:
#setattr(d,choice,laugh) #动态添加一个属性
setattr(d,"alex","sb") #动态加入一个属性
print(getattr(d,"alex"))
运行结果如下:
>>:alex
sb

添加动态方法:

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self,food):
print("%s is eating......%s" %(self.name,food)) def talk(name):
print("%s is talking....." %name) def laugh(self):
print("%s is laughing....." %self) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
if hasattr(d,choice):
'''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
func = getattr(d,choice)
print(func)
# func("chenronghua")
#getattr(d,choice)("chenronghua") else:
setattr(d,choice,laugh) #动态添加一个属性
#setattr(d,"alex","sb") #动态加入一个属性
print(getattr(d,choice)("alex"))

其实,setattr(obj,name_str,属性/方法)就是把一个属性/方法赋值给name_str,如果第三参数是一个方法,那么就赋值了一个方法给name_str,如果第三参数是一个属性,那么就赋值一个属性给name_str,是属性,使用getattr(obj,name_str)得到的是一个字符串;是方法,使用get(obj,name_str)得到的是一个方法的内存地址,其实本质还是上面的getattr(),方法就要看是否有参数,有参数就加入参数调用执行,没有参数就直接加括号执行。

    4.delattr(obj, name, /)
    Deletes the named attribute from the given object.
    
    delattr(x, 'y') is equivalent to ``del x.y''

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self,food):
print("%s is eating......%s" %(self.name,food)) def talk(name):
print("%s is talking....." %name) def laugh(self):
print("%s is laughing....." %self) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
if hasattr(d,choice):
'''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
func = getattr(d,choice)
print(func)
# func("chenronghua")
#getattr(d,choice)("chenronghua") else:
setattr(d,choice,laugh) #动态添加一个属性
#setattr(d,"alex","sb") #动态加入一个属性
getattr(d,choice)("alex")
delattr(d,choice) #删除属性或者方法
getattr(d, choice)("alex")

delattr(obj,name_str)删除实例中的方法或者属性。

    反射:

hasattr(obj,attr),判断一个对象里是否有对应的字符串的方法

getattr(obj,name_str),根据字符串去获取obj对象里对应的方法的内存地址。

setattr(obj,name_str,z)等价于obj.name_str = z

delattr(obj,name_str)删除实例汇总的方法或属性

class Dog(object):

    def __init__(self,name):
self.name = name def eat(self,food):
print("%s is eating......%s" %(self.name,food)) def talk(name):
print("%s is talking....." %name) def laugh(self):
print("%s is laughing....." %self) d = Dog("alex")
choice = input(">>:").strip() #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
set_what = input("把那个变量赋值给属性:").strip() if hasattr(d,choice):
getattr(d,choice)
else:
setattr(d,choice,laugh)
v = getattr(d,choice)
if type(v) == str:
print(v)
else:
print(v("alex"))
运行结果如下:
>>:alex
把那个变量赋值给属性:sb
alex is laughing.....
None

上面实例是对setattr()的进一步补充,其实就是设置属性或者方法。

day7面向对象--反射的更多相关文章

  1. Python之路,Day7 - 面向对象编程进阶

    本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 经典类vs新式类 把下面代 ...

  2. Python之面向对象反射

    Python之面向对象反射 isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(object): 2 pass 3 4 obj = Foo() 5 6 ...

  3. day26.面向对象-反射封装内置方法

    封装 隐藏对象的属性和实现细节,近对外提供公共访问方式 广义:代码保护,面向对象思想 狭义:将属性,方法隐藏起来 class Person: __key = 123456 # 私有的静态属性 def ...

  4. Python之旅Day7 面向对象&异常处理

    ########################################面向对象初识######################################### 面向对象简介 面向对象编 ...

  5. python -- 面向对象 - 反射

    1.isinstance ,type, issubclass       isinstance:判断给的对象是否是**类型       type:返回**对象的数据类型       issubclas ...

  6. 面向对象 反射 和item系列和内置函数和__getattr__和__setattr__

    反射 反射主要用在网络编程中, python面向对象的反射:通过字符串的形式操作对象相关的属性.python的一切事物都是对象. 反射就是通过字符串的形式,导入模块:通过字符串的形式,去模块寻找指定函 ...

  7. Python之面向对象-反射

    一.什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问,检测和修改它本省状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被 ...

  8. day7 面向对象进阶

    面向对象高级语法部分 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例 ...

  9. python全栈开发从入门到放弃之面向对象反射

    1.classmethod.staticmethod方法 classmethod类方法默认参数cls,可以直接用类名调用,可以与类属性交互 #student文件内容 宝宝,男 博博,女 海娇,男 海燕 ...

随机推荐

  1. kubernetes 1.9部署实践

    目录 简要说明 环境说明 安装前的约定 配置etcd 生成相关证书 证书类型说明 cfssl配置 证书相关配置 生成ca证书 生成kubernetes证书 生成kubectl证书 生成kube-pro ...

  2. layoutSubviews何时被调用

    layoutSubviews在以下情况下会被调用: 1.init初始化不会触发layoutSubviews 但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时, ...

  3. (转)tomcat+nginx+redis实现均衡负载、session共享(一)

    在项目运营时,我们都会遇到一个问题,项目需要更新时,我们可能需先暂时关闭下服务器来更新.但这可能会出现一些状况: 1.用户还在操作,被强迫终止了(我们可以看日志等没人操作的时候更新,但总可能会有万一) ...

  4. Git为某个域名设置代理

    打开Git 配置文件 vi ~/.gitconfig 添加如下配置: [http "https://github.com/"] proxy = http://127.0.0.1:1 ...

  5. python 分布式进程体验

    抽了点时间体验了一把python 分布式进程,有点像分布式计算的意思,不过我现在还没有这个需求,先把简单体验的脚本发出来,供路过的各位高手指教 注:需要先下载multiprocessing 的pyth ...

  6. 转 -- OK6410 tftp下载内核、文件系统以及nand flash地址相关整理、总结

    转载地址:http://emouse.cnblogs.com/ 飞凌官方提供了一键下载烧写linux的方式,相对来说比较方便,但是对于开发来说不够灵活,因此这篇文章把tftp相关的点介绍一下,整理下其 ...

  7. Tju_Oj_2790Fireworks Show

    这个题主要在于时间复杂度的计算,N是10的6次方,C是10的2次方,OJ系统可接受的时间是10的7次方(室友说是无数先人测出来了┭┮﹏┭┮),所以如果普通遍历的话肯定会超时.而代码中是跳着走了,相当于 ...

  8. Rico Board.1.环境配置

    1.搭建开发环境 1.解压文件 sudo tar -jvxf gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_liunx.tar.bz2 -C ...

  9. UNIX环境高级编程 第4章 文件和目录

    第三章说明了关于文件I/O的基本函数,主要是针对普通regular类型文件.本章描述文件的属性,除了regular文件还有其他类型的文件. 函数stat.fstat.fstatat和lstat sta ...

  10. msfpayload反弹shell

    1.前期-- 情景就是当我们获得webshell时,我们想留下我们的后门,这个时候我们可以用到msfpayload与msfconsole结合使用 启动PostgreSQL服务:service post ...