面向对象【day08】:反射的最佳实践(三)

本节内容

1、伪造web框架的路由系统

2、反射函数

3、扩展导入模块

4、企业最佳实践

一、伪造web框架的路由系统

commons.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def login():
    print('炫酷登录页面')

def logout():
    print('炫酷退出页面')

def home():
    print('炫酷主页面')

index.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import conmmons


def run():
    inp = input('请输入要访问的url')
    # inp 字符串类型 inp="login"
    # commons inp() #commons.login
    # 利用字符串的形式去对象(模块)中操作(寻找/检查)成员

    if hasattr(commons, inp):
        func = getattr(commons, inp)
        func()
    else:
        print('404')


if __name__ == '__main__':
    run()

基于字符串的形式去对象(模块)中操作其成员

manager.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def order():
    print('炫酷的当单页面')

account.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def login():
    print('炫酷登录页面')

def logout():
    print('炫酷退出页面')

commons.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-


def home():
    print('炫酷主页面')

index.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import conmmons


def run():
    inp = input('请输入要访问的url')
    # inp 字符串类型 inp="login"
    # commons inp() #commons.login
# 利用字符串的形式去对象(模块)中操作(寻找/检查/删除、设置)成员,反射
m, f = inp.split('/') 
obj = __import__(m)
if hasattr(obj, f):
  func = getattr(obj, f)
func()
else:
  print('404')

if __name__ == '__main__':
   run()

tornado框架中的应用

tornado程序源码逻辑图

二、反射函数

2.1、hasarttr(obj,name_str)

作用:判断一个对象obj中是否有对应的name_str字符串的属性或者方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Dog(object):
 
    def __init__(self,name):
        self.name = name
 
    def eat(self,food):
        print("{0} is eating...{1}".format(self.name,food))
 
= Dog("shabi")
choice = input(">>>:").strip()
 
print(hasattr(d,choice))  #obj中是否有对应的choice字符串的属性或者方法
 
#输出
>>>:name  #输入对象存在属性
True
>>>:eat  #输入对象存在的方法
True

2.2、getattr(obj,name_str)

作用:根据字符串name_str获取obj对象中的对应方法的内存地址或者对应属性的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Dog(object):
 
    def __init__(self,name):
        self.name = name
 
    def eat(self,food):
        print("{0} is eating...{1}".format(self.name,food))
 
= Dog("shabi")
choice = input(">>>:").strip()
 
print(getattr(d,choice))  #choice获取obj对象中的对应方法的内存地址或者对应属性的值
 
#输出
>>>:name  #返回name属性的值
shabi
>>>:eat
<bound method Dog.eat of <__main__.Dog object at 0x00000157A129CF28>>  #返回eat方法的内存地址

2.3、setattr(x,y,z)

作用:给obj对象添加一个新属性或者新方法,setattr(x, 'y', v) is equivalent to ``x.y = v''

①给对象新增一个新方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def bulk(self):  #先定义一个bulk函数
    print("{0} is yelling...".format(self.name))
 
class Dog(object):
 
    def __init__(self,name):
        self.name = name
 
    def eat(self,food):
        print("{0} is eating...{1}".format(self.name,food))
 
= Dog("shabi")
choice = input(">>>:").strip()
 
setattr(d,choice,bulk)  #输入的是talk,所以又等同于d.talk = bulk
#d.talk(d) 直接写死,用d.talk(d),一般不这么写
func = getattr(d,choice) #用getattr来获取
func(d)
 
#输出
>>>:talk
shabi is yelling...

②给对象新增一个属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Dog(object):
 
    def __init__(self,name):
        self.name = name
 
    def eat(self,food):
        print("{0} is eating...{1}".format(self.name,food))
 
= Dog("shabi")
choice = input(">>>:").strip()
 
setattr(d,choice,22)  #输入的是age,所以又等同于d.age = 22
# print(d.age) 这样就写死了,还是用下面一种
print(getattr(d,choice))
 
#输出
>>>:age
22

2.4、delattr(x,y)

 作用:删除obj对象中的属性或者方法,delattr(x, 'y') is equivalent to ``del x.y''

 

三、扩展:导入模块

index.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import conmmons


def run():
    inp = input('请输入要访问的url')
    # inp 字符串类型 inp="login"
    # commons inp() #commons.login
    # 利用字符串的形式去对象(模块)中操作(寻找/检查/删除、设置)成员,反射

    m, f = inp.split('/')
    #import lib.account
    obj = __import__("lib."+m, fromlist=True)
    if hasattr(obj, f):
        func = getattr(obj, f)
        func()
    else:
        print('404')


if __name__ == '__main__':
    run()

四、企业最佳实践

import xxx

from xxx import ooo

obj = __import__("xxx")
obj = __import__("xxx.oo.xxx",fromlist=True)
posted @ 2018-06-05 19:51  活的潇洒80  阅读(181)  评论(0编辑  收藏  举报