# -*- coding:utf-8 -*-
#在看廖雪峰的python3.5教学时,看到面向对象高级编程_定义类
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319098638265527beb24f7840aa97de564ccc7f20f6000
百度了很久没有找到想要的答案,想了很久,总结了一点点心得,写的不好,希望大家指正
途中发现好多问题,包括前面没有理解的,停留了好久
##################################
#正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错。比如定义Student类: class Student(object): def __init__(self):
self.name = 'Michael' #调用name属性,没问题,但是,调用不存在的score属性,就有问题了:
#>>> s = Student()
#>>> print(s.name)
#Michael
#>>> print(s.score)
#Traceback (most recent call last):
# ...
#AttributeError: 'Student' object has no attribute 'score' #错误信息很清楚地告诉我们,没有找到score这个attribute。
#要避免这个错误,除了可以加上一个score属性外,Python还有另一个机制,那就是写一个__getattr__()方法,动态返回一个属性。修改如下: class Student(object): def __init__(self):
self.name = 'Michael' def __getattr__(self, attr):
if attr=='score':
return 99 #当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性,这样,我们就有机会返回score的值: #>>> s = Student()
#>>> s.name
#'Michael'
#>>> s.score
#99 #返回函数也是完全可以的: class Student(object): def __getattr__(self, attr):
if attr=='age':
return lambda: 25 #只是调用方式要变为:
#>>> s.age()
#25 #注意,只有在没有找到属性的情况下,才调用__getattr__,已有的属性,比如name,不会在__getattr__中查找。 #此外,注意到任意调用如s.abc都会返回None,这是因为我们定义的__getattr__默认返回就是None。要让class只响应特定的几个属性,我们就要按照约定,抛出AttributeError的错误: class Student(object): def __getattr__(self, attr):
if attr=='age':
return lambda: 25
raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr) #这实际上可以把一个类的所有属性和方法调用全部动态化处理了,不需要任何特殊手段。 #这种完全动态调用的特性有什么实际作用呢?作用就是,可以针对完全动态的情况作调用。 #举个例子: #现在很多网站都搞REST API,比如新浪微博、豆瓣啥的,调用API的URL类似: #http://api.server/user/friends
#http://api.server/user/timeline/list
#如果要写SDK,给每个URL对应的API都写一个方法,那得累死,而且,API一旦改动,SDK也要改。 #利用完全动态的__getattr__,我们可以写出一个链式调用: class Chain(object): def __init__(self, path=''):
self._path = path def __getattr__(self, path):
return Chain('%s/%s' % (self._path, path)) def __str__(self):
return self._path __repr__ = __str__ #测试结果
#>>> Chain().status.user.timeline.list
#'/status/user/timeline/list' #==========================================
#这里想了很久;查看一个类
#创建了一个空的类,再创建一个实例实例 class Student(object):
pass #bart = Student()
#变量bart指向的就是一个Student的实例 #再看刚刚那个例子,Chain()表示类自己(本身);
#Chain().status表示的类Chain()的status属性,此时函数就去寻找Chain的status属性
#但发现没有此属性,这时特殊函数__getattr__起作用了,它帮我们创建属性status属性
#根据定义的方法将新的属性前加一个'/' #初始化使用了默认参数path为空
#def __init__(self, path=''): #连贯起来就是
#1.先定义类Chain()的一个属性path,切默认值为'',为空
#2.定义方法,特殊函数__getattr__遇到未定义的属性默认返回空,不报错
#由于定义了方法,所以返回return Chain('%s/%s' % (self._path, path))
#即将未定义的额属性以'/'为分隔符输出
#3.方法def __str__(self):的作用是打印字符串 #当然还有细节没有搞清楚
#1.class中的各方法参数是表示同一个值吗?
#即三个方法中的self._path相关么?

最新文章

  1. 解决fedora25安装vmware12问题:
  2. hdfs 复制路径下所有文件
  3. 多线程编程-工具篇-BlockingQueue
  4. js实现对移动设备的检测
  5. dstoon系统中学习
  6. new与malloc
  7. FineUI(专业版)高清大图赏析!(第二波)
  8. Linux系统入门学习:在curl中设置自定义的HTTP头
  9. JavaScript执行顺序分析
  10. Google 推出全新的两步验证机制
  11. 130行C语言实现个用户态线程库——ezthread
  12. 百度地图点击地图显示地址详情的默认方法怎么关闭,去掉百度地图api图标信息
  13. mac用户丢失管理员身份急救
  14. saltstack 入门
  15. Enable Coded UI Testing of Your Controls
  16. SCRIPT438: 对象不支持“indexOf”属性或方法
  17. ARM Mcp2515添加驱动
  18. MySQL 大表数据定期归档
  19. vue_表单控件
  20. windows下的pycharm配置 linux环境

热门文章

  1. weui 中的tabbar导航
  2. JavaScript 数组对象的去重
  3. 线程池的使用及ThreadPoolExecutor的分析(一)
  4. 使用quartz实现不重启服务器修改自定义配置
  5. sublime 设置新建文件自动添加author(作者)等文件头信息
  6. canvas图像处理汇总
  7. 利用python写一个简单的小爬虫 爬虫日记(1)(好好学习)
  8. bzoj 4605: 崂山白花蛇草水
  9. bzoj:1673 [Usaco2005 Dec]Scales 天平
  10. ElasticSearch + xpack 使用.md