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天前
|
SQL API Python
Python DB API下规范下cursor对象常用接口
Python DB API下规范下cursor对象常用接口。
21 4
|
1天前
|
存储 Java 数据安全/隐私保护
Python----类对象和实例对象
Python----类对象和实例对象
9 2
|
2天前
|
存储 安全 Java
Python中的引用和赋值机制允许变量引用内存中的对象,并通过引用计数来管理对象的生命周期
【5月更文挑战第14天】Python中的变量是对象引用,不存储数据,而是在内存中创建对象。赋值操作创建新变量并使其指向已有对象。引用计数用于管理对象生命周期,引用数为0时对象被回收。理解这些机制对编写高效Python代码很重要。
17 6
|
2天前
|
C++ Python
Python中的类与对象
Python中的类与对象
6 1
|
2天前
|
缓存 Java Python
Python 弱引用全解析:深入探讨对象引用机制!
Python 弱引用全解析:深入探讨对象引用机制!
22 3
|
2天前
|
运维 Shell Sentinel
第八章 Python可迭代对象、迭代器和生成器
第八章 Python可迭代对象、迭代器和生成器
|
2天前
|
数据安全/隐私保护 Python
Python从入门到精通——2.2.1深入学习面向对象编程:类和对象的定义
Python从入门到精通——2.2.1深入学习面向对象编程:类和对象的定义
|
2天前
|
数据库 Python
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(下)
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)
49 0
|
2天前
|
Python
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
62 0
|
2天前
|
Python
python学习12-类对象和实例对象
python学习12-类对象和实例对象