__getattr__动态获取接口
# -*- 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相关么?
__getattr__动态获取接口的更多相关文章
- vue项目接口域名动态获取
需求: 接口域名是从外部 .json 文件里获取的. 思路: 在开始加载项目前 进行接口域名获取,然后重置 接口域名的配置项. 实现: 1.config/index.js 文件 进行基础配置 impo ...
- @SpringContext通过实现ApplicationContextAware接口动态获取bean
场景: 在代码中需要动态获取spring管理的bean 目前遇到的主要有两种场景:1.在工具类中需要调用某一个Service完成某一个功能,如DictUtils2.在实现了Runnable接口的任务类 ...
- java最全的获取某个接口或者某个类所有对应的所有实现类和继承类的工具类--反射动态获取、非动态获取、按照路径获取等总结
我们直接上代码吧,代码中有注释说明. //直接看代码吧 import java.io.File; import java.lang.reflect.Field; import java.net.URL ...
- 动态获取ul,li的数据
通过一个小例子讲下动态获取li标签的数据,前台页面原有样式: <div class="flone"> <ul class="fltwo"> ...
- 动态获取爱奇艺上传视频mp4格式url地址
有时候,在工作中有些客户需要用到视频,我们大家都知道视频是非常的耗费流量的,因此,如果因为项目要求客户单独买台视频服务器是非常划不来的.那么将视频上传到优酷,爱奇艺等视频网站来托管那是一件很好的解决方 ...
- SpringMVC——使用RequestDispatcher.include()和HttpServletResponseWrapper动态获取jsp输出内容
介绍本篇内容前,先抛出我遇到的问题或者说是需求!(精读阅读本篇可能花费您15分钟,略读需5分钟左右) 一:需求说明 有一个Controller有两个方法 第一个方法通过指定的路径和参数去渲染jsp内容 ...
- 微信公众号开发C#系列-4、获取接口调用凭证
概述 获取接口调用凭证实质就是获取access_token.在微信接口开发中,许多服务的使用都离不开Access Token,Access Token相当于打开这些服务的钥匙,正常情况下会在7200秒 ...
- 微信小程序之动态获取元素宽高
我以前一直以为微信小程序不能动态获取view元素的宽高.但是自从看到: wx.createSelectorQuery() 这个api接口,以前的某些问题就能得到解决了... 那么,这个api接口怎么用 ...
- 使用os模块动态获取目录或文件路径
在接口自动化测试框架中,我们的代码除了能在本地运行,也能在不在修改代码的前提下在其他的环境下能够运行,这样才能达到高复用性和低维护成本,我们在接口测试的模块调用中,会定义很多相关路径,而这些路径必须使 ...
随机推荐
- conda虚拟环境实践
1.查看本地创建了那些python版本 which python whereis python which主要用来查找可直接执行的命令,可以查找别名.whereis比which的搜索范围大了一些,同时 ...
- python 数据类型之集合
一.集合的定义: 定义:由不同元素组成的集合,集合中是一组无序排列的可hash值,可以作为字典的key. 特性:集合的目的是将不同的值存放到一起,不同的集合间用来做关系运算,无需纠结于集合中单个值 二 ...
- 树和二叉树的存储结构的实现(C/C++实现)
存档: #include <iostream.h> #include <stdio.h> #include <stdlib.h> #define max 20 ty ...
- CTF---Web入门第九题 FALSE
FALSE分值:10 来源: iFurySt 难度:易 参与人数:4567人 Get Flag:2144人 答题人数:2157人 解题通过率:99% PHP代码审计 hint:sha1函数你有认真了解 ...
- Codeforces Round #300(Div. 2)-538A.str.substr 538B.不会 538C.不会 。。。
A. Cutting Banner time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- POJ_1064 二分搜索
/*POJ 1064 *题目大意:有N条绳子,他们的长度分别为Li,如果从他们中切割K条长度相同的绳子的话,这K条绳子每条最长能有多长?答案保留到小数点后2位 *算法分析:这个问题用二分搜索可以非常容 ...
- win10系统下如何用命令行的方式打开画图软件
按 win + r 后输入命令 mspaint 再 回车 即可!如下图所示:
- linux下vi编辑某文件时,操作出现 错误提示: E325: ATTENTION 2, Found a swap file by the name ".p1.c.swp"
当我在linux下用vi打开p1.c文件时 root@iZ2zeeailqvwws5dcuivdbZ:~/1/01/指针# vi p1.c 会出现如下信息: E325: ATTENTION Found ...
- 在 .NET中,一种更方便操作配置项的方法
在应用程序的开发过程中,我们往往会为软件提供一些配置项,以允许软件根据配置项灵活来做事情,比如配置日志文件路径等,此外,我们还可以用配置项来为用户存储其偏好设置等. .NET 为我们默认提供了配置机制 ...
- [国嵌笔记][025][ARM指令分类学习]
算术和逻辑指令 1.mov 格式:mov {条件}{s} <dest>, <op> 作用:把一个值从一个地方移动到另一个地方,<dest>必须是寄存器 示例: @m ...