8.python之面相对象part.6(反射&__call__,__setattr__,__delattr__,__getattr__)

简介:

一.什么是反射?

反射,又被称为自省,主要是指程序本身可以访问,检测,和修改“自己”,状态或行为的一种能力。


二.python是如何体现这种反射机制的?

通过字符串去操作对象相关的属性,python中,一切皆对象,所有的地方都可以用到反射。

python内部提供了四个实现反射(自省)的函数,这四个函数可以适用于任何的类和对象(这是因为类本身也是一个对象!)


1.hasattr(object,str) 用来检测一个对象中是否有某个字符串对应的方法或者属性。

例如:

l1 = []

print hasattr(l1,"append")

True

#如果一个对象中有以这个字符串命名的属性或者方法,那么就回直接返回True,否则就回返回False。

#在一个列表中是没有keys方法的。

l1 = []

print hasattr(l1,"keys")

False


2.getattr(object,str,defaultstr) 通过一个字符串去获取一个对象的属性或者方法,如果找不到指定的属性或者方法默认情况下会抛出异常。

l1 = [1,2,3]

print getattr(l1,"pop")

#获取l1这个对象的pop方法,结果pop方法就获取到了,在后面加个括号就可以执行。

<built-in method pop of list object at 0x1076097a0>

print getattr(l1,"pop")()


当要在一个对象中查找一个属性或者方法时,这个方法不存在,又不希望直接抛出异常,这时候就要使用getattr的第三个参数,这个参数可以指定如果找不到指定属性或者方法默认返回的值是什么。

l1 = [1,2,3]

print getattr(l1,"aaaaaaa","i dont know")

#在l1这个对象中查找名为aaaaaaa的方法,如果找不到,就返回一个i dont know。

i dont know


3.setattr(object,key,value) 通过字符串的方式,给一个对象创建一个新的属性,同时也可以修改一个对象原来的属性。

class test(object):

    def __init__(self):

        self.test = "test"

test1 = test()

print test1.test

test

setattr(test1,"test","ayumi")

#修改一个对象中的属性

print test1.test

ayumi

setattr(test1,"aaa","bbb")

#给一个对象添加一个属性。

print test1.aaa

bbb



4.delattr(object,str) 通过字符串删除一个对象中的一个属性或者方法,当被删除的属性不存在时就会报错。


三.__call__,__setattr__,__delattr__,__getattr__

  1. __call__方法用于对象自身的调用。

当一个对象后面加()小括号调用自己的时候,就会触发自身的__call__方法,__call__方法下面的代码就回被执行。

class person(object):

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __call__(self, *args, **kwargs):

        print "执行了__call__方法"

        print self.name

        print self.age

ayumi = person("hamasakiayumi","38")

#ayumi现在是一个对象,在对象后面直接加()小括号,就回执行__call__方法下面的代码。

ayumi()

输出:

执行了__call__方法

hamasakiayumi

38


2.__getattr__ 当要调用的属性不存在时,就会触发__getattr__下面的方法。

class person(object):

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __call__(self, *args, **kwargs):

        print "执行了__call__方法"

        print self.name

        print self.age

    def __getattr__(self, item):

        print "此方法或属性不存在"

#当找不到指定属性或者方法的时候,就触发__getattr__方法,print "此方法或属性不存在"

ayumi = person("hamasakiayumi","38")

ayumi.assasasaas

输出:

此方法或属性不存在


3.__setattr__当修改一个对象或者类的属性的时候,会触发__setattr__方法,它本身也用来设置对象中的属性。

class person(object):

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __call__(self, *args, **kwargs):

        print "执行了__call__方法"

        print self.name

        print self.age

    def __getattr__(self, item):

        print item

        print "此方法或属性不存在"

    #def __setattr__(self, *args, **kwargs):

        #print "触发__setattr__方法"

        #return object. __setattr__(self,*args,**kwargs)

       

    def __setattr__(self, key, value):

        print "触发__setattr__方法"

        # self.key=value #这就无限递归了,你好好想想

         self.__dict__[key]=value #应该使用它

其实上面这两种写法实现的功能都是一样的,下面这种写法更容易理解,直接修改了__dict__这个属性的字典。


ayumi = person("hamasakiayumi","38")

ayumi.song = "fly high"

#为一个对象增加一个属性,__setattr__方法就被执行了。

print ayumi.song

输出:

触发__setattr__方法

触发__setattr__方法

触发__setattr__方法

fly high



4.__delattr__当删除一个对象中的某个属性,或者某个方法时,会触发__delattr__这个方法。

class person(object):

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __call__(self, *args, **kwargs):

        print "执行了__call__方法"

        print self.name

        print self.age

    def __getattr__(self, item):

        print item

        print "此方法或属性不存在"

    def __setattr__(self, *args, **kwargs):

        print "触发__setattr__方法"

        return object. __setattr__(self,*args,**kwargs)

    

#    def __delattr__(self, *args, **kwargs):  

#      print 'call func del attr'  

#       return object.__delattr__(self, *args, **kwargs)  

#   这种写法是继承新式类中实现过的__delattr__方法。

    def __delattr__(self, item):    #当使用del关键词删除一个属性或者方法的时候,__delattr__下面的代码

        print  "触发__delattr__方法"                                                                                           就会被触发。

        self.__dict__.pop(item)  #这个是删除的动作。

ayumi = person("hamasakiayumi","38")


注意!!__call__,__setattr__,__delattr__,__getattr__这四种方法,系统默认已经定义好了,当有特殊需求的时候,才需要自己去定义。





      本文转自苏浩智 51CTO博客,原文链接:http://blog.51cto.com/suhaozhi/1917254,如需转载请自行联系原作者





相关文章
|
2月前
|
Python
python对象模型
这篇文章介绍了Python中的对象模型,包括各种内置对象类型如数字、字符串、列表、字典等,以及如何使用`type()`函数来查看变量的数据类型。
|
2月前
|
Python
探索Python中的魔法方法:打造你自己的自定义对象
【8月更文挑战第29天】在Python的世界里,魔法方法如同神秘的咒语,它们赋予了对象超常的能力。本文将带你一探究竟,学习如何通过魔法方法来定制你的对象行为,让你的代码更具魔力。
40 5
|
2天前
|
存储 缓存 Java
深度解密 Python 虚拟机的执行环境:栈帧对象
深度解密 Python 虚拟机的执行环境:栈帧对象
35 13
|
2天前
|
索引 Python
Python 对象的行为是怎么区分的?
Python 对象的行为是怎么区分的?
8 3
|
2天前
|
存储 缓存 算法
详解 PyTypeObject,Python 类型对象的载体
详解 PyTypeObject,Python 类型对象的载体
11 3
|
1天前
|
Python
深入解析 Python 中的对象创建与初始化:__new__ 与 __init__ 方法
深入解析 Python 中的对象创建与初始化:__new__ 与 __init__ 方法
7 1
|
2天前
|
缓存 Java 程序员
一个 Python 对象会在何时被销毁?
一个 Python 对象会在何时被销毁?
9 2
|
2天前
|
API Python 容器
再探泛型 API,感受 Python 对象的设计哲学
再探泛型 API,感受 Python 对象的设计哲学
9 2
|
2天前
|
API Python
当调用一个 Python 对象时,背后都经历了哪些过程?
当调用一个 Python 对象时,背后都经历了哪些过程?
12 2
|
2天前
|
存储 API C语言
当创建一个 Python 对象时,背后都经历了哪些过程?
当创建一个 Python 对象时,背后都经历了哪些过程?
9 2