__setattr__,setattr(),getattr__,getattr()及__getattribute__的区别

__setattr__,setattr(),getattr__,getattr()及__getattribute__的区别Python2.7IDEPycharm5.0.3首先,给一波定义__setattr__(self,name,value)#当试图给特性name赋值时候自动被调用,其余方法同理#相当于触发机制__getattribute__(self,item)#每次通过实例化访问属性都会通过该函数#如果没有该属性,则访问完该函数后,再会通过__getattr__函数_setattr_和_get

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

Python 2.7
IDE Pycharm 5.0.3

首先,给一波定义

__setattr__(self,name,value)
#当试图给特性name赋值时候自动被调用,其余方法同理
#相当于触发机制

__getattribute__(self,item)
#每次通过实例化访问属性都会通过该函数
#如果没有该属性,则访问完该函数后,再会通过__getattr__函数

Jetbrains全家桶1年46,售后保障稳定


_setattr__getattr_

这里下面用网上比较热的代码进行测试和注释,因本人接触Python不足两星期,若有纰漏,请君不吝赐教;

class Book(object):
    def __setattr__(self, key, value):
        #给特性key赋值时候会被自动调用
        if key == 'value1':#当name这个特性是'value1'时
            print "key=value1时候跳进来了"
            object.__setattr__(self, key, value - 100)#这个value1属性的值value=100,分清value和value1
        else:
            print "设置时候跳入else了"
            object.__setattr__(self, key, value)#正常设置呗

    def __getattr__(self, name):
        try:
            print "__getattr__被调用"
            return object.__getattribute__(name)#__getattribute__当name被访问时就被调用

        except:
            return name + ' is not found!'

    def __str__(self):
        print "__str__被调用"
        return self.name + ' cost : ' + str(self.value1)#这句作用是为了print c的时候显示而已

c = Book()

c.name = 'Python'#这里key = name,value= 'Python'
c.value1 = 100#凡是对属性进行设置的都会进入__setattr__()中
print "---------c.name--------"
print c.name#动态建立属性name,本身在class中不存在,故才调用__getattr__
print "--------c.value1-------"
print c.value1
print "-----------c-----------"
print c
print "---------c.Type--------"
print c.Type#看看有没有Type属性

结果如下:

设置时候跳入else了
key=value1时候跳进来了

---------c.name--------

Python

--------c.value1-------

0

-----------c-----------

__str__被调用
Python cost : 0

---------c.Type--------

__getattr__被调用
Type is not found!

注释解释的比较详细了,几乎把这几个函数都用了个遍,自己多看看多总结会有更多的收获,或许以后的某一天我回过头开看这段代码会显得多幼稚呢,哈哈。


setattr()和getattr()

接下来是对setattr()和getattr()的分析,刚开始学总容易把这个方法和上述的__setattr__()搞混,接下来演示下setattr()和getattr()方法的使用。

class GSA_atte():

    def __init__(self):
        self.num = 9
    def power(self):
        return self.num*self.num

gsa = GSA_atte()#类都要实例化,方法都是对实例进行操作的
print hasattr(GSA_atte(),'num')#相当于有没有num属性,返回布尔类型
print getattr(gsa,'num')#也可以用实例gsa
print getattr(gsa,'y','获取不到y属性')
#getattr(类名,'属性','没有这个属性输出这里')
#也可以用try,except语句来进行包裹代替上句
try:
    getattr(gsa,'y')
except:
    print('no y')

setattr(gsa,'y',10)#setatta不需要print
print '经过setattr设置参数之后,得到y:',getattr(gsa,'y')

程序跑出来的结果是:

------------hasattr(GSA_atte(),'num')--------- 
True

--------------getattr(gsa,'num')-------------- 
9

--------getattr(gsa,'y','获取不到y属性')-------- 
获取不到y属性

-----------------try--except----------------- 
no y

---------经过setattr设置参数之后,得到y:-------- 
经过setattr设置参数之后,得到y: 10

相信大家好好看下代码注释及结果就可以很快的理解其中的奥秘了。


7.18补充:_get_,_getattr_,_getattribute__call_

class C(object):
    a = 'abc'
    def __getattribute__(self, *args, **kwargs):
        print("__getattribute__() is called")
        return object.__getattribute__(self, *args, **kwargs)

    def __getattr__(self, name):
        print("__getattr__() is called ")
        return name + " from getattr"

    def __get__(self, instance, owner):
        print("__get__() is called", instance, owner)
        return self

    def __call__(self, x):
        print("__call__ is called")
        print "x :"+str(x)

class C2(object):
    d = C()

if __name__ == '__main__':
    c = C()
    c2 = C2()
    print "------------c.a-------------"
    print(c.a)
    print "---------c.zzzzzz-----------"
    print(c.zzzzzz)
    print "-----------c2.d-------------"
    c2.d
    print "-----------c2.d.------------"
    print(c2.d.a)#d是作为C2的一个属性被调用
    print "----------c(200)------------"
    print c(200)

运行结果是:

------------c.a-------------

__getattribute__() is called
abc

---------c.zzzzzz-----------

__getattribute__() is called
__getattr__() is called 
zzzzzz from getattr

-----------c2.d-------------

('__get__() is called', <__main__.C2 object at 0x0000000002DA92E8>, <class '__main__.C2'>)

-----------c2.d.------------

('__get__() is called', <__main__.C2 object at 0x0000000002DA92E8>, <class '__main__.C2'>)
__getattribute__() is called
abc

----------c(200)------------

__call__ is called
x :200
None

最后

果然基础语法还是需要多看多练习,不然真的就忘了,越不用越忘,以后看高级一点的项目代码可能就会很累了。


致谢

@MaxOmnis–python call 内置函数的使用
@luozhaoyu–python中get,getattr,getattribute的区别

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226819.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何申请注册在国内可以登录使用国外邮箱?「建议收藏」

    如何申请注册在国内可以登录使用国外邮箱?「建议收藏」2022年冬奥会的开始、冰墩墩的爆火,这些让在国外无法回国的华人,十分羡慕,也让很多之前不怎么联系的朋友使用邮件交流了起来,那么是不是所有邮箱都可以向国外发信呢?其实并不是,我之前使用过,很多邮箱都是无法向国外发信的,现在我注册使用的是TomVIP邮箱,公司使用的Tom企业邮箱,因为做出口贸易,才选择的这家邮箱,在国外收发信方面做的还是非常棒的!如何申请注册国外邮箱首先,要进入邮箱官网(网页进行搜索、网址直接进入),选择自己喜欢的邮箱域名,点击注册;其次,选择邮箱套餐,依据自己日常使用的邮箱容量、发信

    2022年7月12日
    91
  • Idea中建多层级包时出现的问题

    Idea中建多层级包时出现的问题刚开始使用idea时发现不会分包。假如我想在com下面分别建Dao、pojo、service包等,会出现每次在上一个包里面建包,并不会使Dao、pojo、service包平级。解决方法:方法一:            1)先在java包下建名为com包,     2)鼠标点击com的上一级包(这里就是java包),然后新建包为com.Dao包。这里会出现不用着急,因为你只有一个包。再继续点击com…

    2022年6月13日
    33
  • PyCharm 教程(五)断点 调试[通俗易懂]

    PyCharm 教程(五)断点 调试[通俗易懂]PyCharm作为IDE,断点调试是必须有的功能。否则,我们还真不如用纯编辑器写的快。【运行】和【调试】前的设置,详见前面的文章,helloword。1,设置断点在代码前面,行号的后面,鼠标单击,就可以设置断点。如下:2,调试断点点击那个绿色的甲虫图标(似乎甲虫已经成为debug专用图标了),进行断点调试。点击后,会运行到第一个断

    2022年5月21日
    27
  • 用js来实现那些数据结构14(树02-AVL树)

    在使用二叉搜索树的时候会出现一个问题,就是树的一条分支会有很多层,而其他的分支却只有几层,就像下面这样:如果数据量够大,那么我们在某条边上进行增删改查的操作时,就会消耗大量的时间。我们花费精力去构

    2022年3月25日
    28
  • 8 款免费的 MySQL 数据库建模工具

    数据库建模和设计是软件开发过程中必不可少的步骤,一个良好的建模工具可以帮助我们简单快速地完成数据库设计,提高工作的效率。因此,今天给大家推荐几款免费的MySQL数据库建模工具,包括MySQLWorkbench、SQLPowerArchitect、PDMan、RISE、GenMyModel、DBDesigner、dbdiagram.io、Freedgo。

    2022年4月8日
    304
  • VMware虚拟机安装Ubuntu20.04详细图文教程[通俗易懂]

    VMware虚拟机安装Ubuntu20.04详细图文教程[通俗易懂]Windows下VM16虚拟机安装Ubuntu20.04下载链接和手把手的详细教程,同时还有更换软件源和命令行安装VMTools实现跨系统复制粘贴教程

    2022年10月1日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号