getattr()
先创建一个类,将所有函数放在类里。在调用前先实例化该类,不论类里有多少个函数,直接根据输入内容通过getattr调用类里的函数.
#!/usr/bin/env python
# coding=utf-8
class getfun:
def fun1(self):
print 'processNavigate'
def fun2(self):
print 'processCreateTab'
action = raw_input('请输入地址:')
newfun = getfun()
fun = getattr(newfun,action)
fun()
getattr的另一个常用示例就是在多个web页面的情况下。在入口文件里经常需要用到getattr函数智能处理不同的页面请求。先看下一个常见的页面结构:
# tree
.
├── backend
│ ├── account.py
│ ├── account.pyc
│ ├── admin.py
│ ├── admin.pyc
│ ├── __init__.py
│ └── __init__.pyc
├── index.py -----> if版入口文件
└── web.py -----> getattr版入口文件
admin.py和account代码比较简单,单纯为了测试,这里只是print内容
[root@www backend]# cat admin.py
#!/usr/bin/env python
# coding=utf-8
def index():
print 'welcome to your, administrator !'
[root@www backend]# cat account.py
#!/usr/bin/env python
# coding=utf-8
def login():
print 'login now ******* '
def logout():
print 'logout now ******* '
先看下if版的用法:
[root@www web]# cat index.py
#!/usr/bin/env python
# coding=utf-8
from backend import account
data = raw_input('请输入地址:')
if data == 'account/login':
account.login()
elif data == 'account/logout':
account.logout()
这里只import了account ,对登陆和登出做了判断。如果需要登陆后台,还要import admin,并对admin里的方法再做判断。同样如果有还blog 、bbs 、usercenter等相关N个页面时,这个判断结构是不可想象的.
getattr的方法处理
[root@www web]# cat web.py
#!/usr/bin/env python
# coding=utf-8
data = raw_input('请输入地址:')
array = data.split('/')
userspance = __import__('backend.'+array[0])
model = getattr(userspance , array[0])
func = getattr(model,array[1])
func()
这里先通过输入内容通过split进行了切分,如输入的account/login ,会切分成数组[ account, login ] ,而输入是admin/index则切分成[ admin, index ] 。由于引用的函数在当前目录下的子目录下,所以这里需要通过backend连接引入。
这里为什么是两次getattr调用才能将结果输出呢?这里其实可以使用入门篇里的dir方法查看,也可以通过使用inspect模块进行判断、获取对象。通过dir分析结果如下:
>>> userspance = __import__('backend.'+ 'admin')
>>> dir(userspance)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'admin']
>>> model = getattr(userspance,'admin')
>>> dir(model)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'index']
>>> getattr(model,'index')
<function index at 0x7f572801a9b0>
>>> getattr(model,'index')()
welcome to your, administrator !
看看直接执行后的效果:
[root@www web]# python web.py
请输入地址:admin/index
welcome to your, administrator !
[root@www web]# python web.py
请输入地址:account/login
login now *******
[root@www web]# python web.py
请输入地址:account/logout
logout now *******
效果非常好,在backend里论有多少个页面,都可以通过这一段完成调用。完全不用做一大堆的import和if 判断。这里之所以和上面不一样两次getattr,是由于引用内容在子目录下。
hasattr、setattr与delattr
先创建一个简单的类:
#!/usr/bin/python
# coding=utf-8
class test:
def __init__(self):
self.name = 'www.le.com'
def setName(self,name):
self.name = name
def getName(self):
return self.name
def greet(self):
print "Hello,I'm %s" %self.name
foo = test()
1、hasattr(object,name)
hasattr判断object中是否具有name属性,返回的是一个布尔值。存在则返回True,不存在返回flase 。
foo = test()
print hasattr(foo,'abc')
在类实例化后,通过上面的方法调用测试,因为不存在abc,方法,所以这里返回flase。将abc更换为getName则返回True 。
2、setattr(object,name,default)
该函数会对现有的name字符串赋值或新增一个name并对其赋值。在对上面的test类实例化为foo后,在其后加入如下代码:
setattr(foo,'age',18)
print getattr(foo,'age')
print getattr(foo,'name')
setattr(foo,'name','newname')
print getattr(foo,'name')
执行后输出内容如下:
18
www.361way.com
newname
3、delattr(object,'name')
其主要用于删除一个name字符串的值。后面新增代码如下:
delattr(foo,'name')
print getattr(foo,'name','not find')
这里执行后的输出为not find 。
源自运维之路
转载于:https://blog.51cto.com/lz001/1828563