python学习笔记-Day08--(反射)

从一开始学习这一块感觉blog就比较难写,本来就不太会写博客的问题就更严重了。

想不出什么形象的比喻。所以要写blog的时候我的心情是这样的,但是我的心情应该调整成这样的

还是用上课时举的例子来说明白。

首先说明一下,反射要用到内置函数,

getattr(obj,name)
hasattr(obj,name)
delattr(obj,name)  #操作内存,不影响文件,很少使用
setattr(obj,name)  #操作内存,不影响文件,很少使用

先看一下getattr()方法的说明

getattr(object, name[, default]) -> value

Get a named attribute from an object; getattr(x, ‘y‘) is equivalent to x.y.When a default argument is given, it is returned when the attribute doesn‘texist; without it, an exception is raised in that case.

从一个对象中得到一个命名的属性, getattr(x,"y")  等价于 x.y

其他三个函数与此类似。

上面的先有个印象就好。下面开始详细说明:

首先我们先考虑一个问题。

当我们访问一个网址的时候,我们可以发现,每一个网址都有一个对应的页面。

最直观的python代码实现就是:

import web

url = raw_input("url:")

if url =="web/url01":

result = web.page01()      #处理页面数据,并返回结果

print  result

elif url =="web/url02":

result = web.page02()    #处理页面数据,并返回结果

print  result

elif url =="web/url03":

result = web.page03()   #处理页面数据,并返回结果

print  result

............

else:

print "404 not found"

web.py的内容如下:

def url01():

return "This is  ur01"

def url01():

return "This is  ur02"

def url01():

return "This is  ur03"

............

如果网页少的时候是没有问题的,但是当网页越来越多的时候,这样做显然是不行的。

优化以后外面可以用下面的办法(没有加url判断,即url不存在的时候)

import web

url = raw_input("url:")

preUrl,endUrl = url.split("/")

func = getattr(web,endUrl)

result = func()

print result

运行代码,如果此时输入的url为     web/url01

那么输出结果为:    This is  ur01

使用正常的代码实现为:(有错误判断)

from wsgiref.simple_server import make_server

def RunServer(environ, start_response):
            start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)])
            url = environ[‘PATH_INFO‘]

# temp 等于方法的名字
            temp = url.split(‘/‘)[1]

#导入web模块
            import web

#判断web模块中是否含有 temp,用与判断成员是否存在
            is_exist = hasattr(web, temp)
            if is_exist:

# 将temp赋值给func,获取函数
                func = getattr(web, temp)
                #ret 得到func()的返回值
                ret = func()
                return ret
            else:
                return ‘404 not found‘

if __name__ == ‘__main__‘:
            httpd = make_server(‘‘, 8001, RunServer)
            print "Serving HTTP on port 8001..."
            httpd.serve_forever()

上面的代码其实就是运行一个httpServer ,如果这个httpServer 得到一个url,就会判断这个url是否存在,如果存在就调用相应的模块和方法,如果不存在就返回 404错误

所有的操作就是对内存中内容的操作

看完下面的代码可能就会明白了

import  web                            # 导入web模块,加载到内存

print dir(web)                         # 查看web模块有那些内容

print hasattr(web,"web_hasattr")        #判断web模块是否含有 “web_hasattr” 方法或属性
print getattr(web,"url01")                     # 得到web模块中的url01方法(或属性,本文中为方法),并打印

setattr(web,"newFun","newFun value")  # 给web模块增加 "newFun" 方法或属性,值为"newFun value"

该操作为内存中的操作,不影响磁盘上的文件,也就是说,源文件不会发生变化         
print dir(web)

print delattr(web,"fun1")# 删除web模块中的 "newFun" 方法或属性
                               同样该操作为内存中的操作,不影响磁盘上的文件,也就是说,源文件不会发生变化  print dir(page01)

对比看六次print的输出结果:
[‘__builtins__‘, ‘__doc__‘, ‘__file__‘, ‘__name__‘, ‘__package__‘, ‘fun1‘, ‘fun2‘, ‘fun3‘, ‘fun4‘, ‘fun5‘]
False
<function fun1 at 0x7fbebff587d0>
[‘__builtins__‘, ‘__doc__‘, ‘__file__‘, ‘__name__‘, ‘__package__‘, ‘fun1‘, ‘fun2‘, ‘fun3‘, ‘fun4‘, ‘fun5‘, ‘newFun‘]
None
[‘__builtins__‘, ‘__doc__‘, ‘__file__‘, ‘__name__‘, ‘__package__‘, ‘fun2‘, ‘fun3‘, ‘fun4‘, ‘fun5‘, ‘newFun‘]

开脑洞的想法:

delattr(obj,name)  和 setattr(obj,name)  都是在内存操作,那么类也是可以存在于内存中的,那么这两个函数同样可以对内存中的类进行操作。

class foo:

staticVar= "staticVar"
            def __init__(self):
                self.var ="var"
            def show(self):
                pass
            @staticmethod
            def sshow():
                pass
            @classmethod
            def cshow(cls):
                pass

obj =foo()
        print dir(obj)
        print obj.__dict__
        print hasattr(obj,"sdf")
        print hasattr(obj,"show")
        输出结果:
        [‘__doc__‘, ‘__init__‘, ‘__module__‘, ‘cshow‘, ‘show‘, ‘sshow‘, ‘staticVar‘, ‘var‘]
        {‘var‘: ‘var‘}
        False
        True

好,继续前面的,前面的代码主要都是使getattr(obj,name)的第二个参数为动态参数来处理不同的url

对于网站来说,不可能把所有的页面处理方法都写在一个文件里,那么如果动态的使用不同文件里的不同方法(或属性)呢?

即 动态的使用  getattr(obj,name)  的第一个参数。

看如下代码:

controller,action = raw_input("url:").split("/")
module = __import__(controller)  #等价于 import 模块名 as module
func=  getattr(module,action)
ret = func()
print ret

这里的代码就是上面所有代码的最终版,

也就是我们所说的反射

我理解的是反射就是

你出发某一个条件,然后系统根据找个条件去做处理,并给你返回处理结果。

就好像经过 巴甫洛夫 训练后的狗

你一摇铃铛 狗就流口水。。。

大神博客地址

http://home.cnblogs.com/u/wupeiqi/

我的blog地址:

http://www.timesnotes.com/?p=139

时间: 2024-08-21 19:24:16

python学习笔记-Day08--(反射)的相关文章

python学习笔记__反射

反射 # 通过字符串的形式对对象中的成员进行操作(获取/查找/添加/删除). 操作的内置函数: 1.获取   getattr(object, name) # 去对象object中获取name的内容 class Foo: def __init__(self, name, age): self.name = name self.age = age obj = Foo('Lemon147', 18) v = getattr(obj, 'name') print(v) >>> Lemon147

OpenCV之Python学习笔记

OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书<OpenCV Computer Vision with Python>,于是就看一遍,顺便把自己掌握的东西整合一下,写成学习笔记了.更需要的朋友参考. 阅读须知: 本文不是纯粹的译文,只是比较贴近原文的笔记:         请设法购买到出版社出版的书,支持正版. 从书名就能看出来本书是介绍在Pytho

python学习笔记12-模块使用

python学习笔记12-模块使用 模块os,sys 什么是模块? 模块os,sys 模块是Python组织代码的一种基本方式 一个Python脚本可以单独运行,也可以导入到另外一个脚本运行,用import hello语句来导入,不用加入.py 什么是Python的 包? Python的模块可以按照目录组织为包 创建一个包的步骤: 创建一个名字为包名的目录 在改目录下创建一个__init__.py文件 根据需要,在该目录下存放脚本文件或已编译的扩展及子包 import pack.m1,pack.

python学习笔记2—python文件类型、变量、数值、字符串、元组、列表、字典

python学习笔记2--python文件类型.变量.数值.字符串.元组.列表.字典 一.Python文件类型 1.源代码 python源代码文件以.py为扩展名,由pyton程序解释,不需要编译 [[email protected] day01]# vim 1.py #!/usr/bin/python        print 'hello world!' [[email protected] day01]# python 1.py hello world! 2.字节代码 Python源码文件

Python学习笔记--未经排版

Python 学习笔记 Python中如何做到Print() 不换行 答:Print("输出内容",end='不换行的分隔内容'),其中end=后面为2个单引号 注:在Python 2.x中,Print "输出内容", 即在输出内容后加一逗号 Python中 is 和 == 的区别 答:Python中的对象包含三要素:id.type.value 其中id用来唯一标识一个对象,type标识对象的类型,value是对象的值 is判断的是a对象是否就是b对象,是通过id来

Python学习笔记_Python对象

Python学习笔记_Python对象 Python对象 标准类型 其他内建类型 类型对象和type类型对象 Python的Null对象None 标准类型操作符 对象值的比较 对象身份比较 布尔类型 标准类型的内建函数 typeObj cmpobj1 obj2 strobj reprobj typeobj isinstanceobj 标准类型的分类 存储模型 更新模型 访问模型 不支持的类型 Python学习笔记_Python对象 首先来理解一个通俗的含义,什么是对象?其实对象无论在什么语言里面

OpenCV for Python 学习笔记 三

给源图像增加边界 cv2.copyMakeBorder(src,top, bottom, left, right ,borderType,value) src:源图像 top,bottem,left,right: 分别表示四个方向上边界的长度 borderType: 边界的类型 有以下几种: BORDER_REFLICATE # 直接用边界的颜色填充, aaaaaa | abcdefg | gggg BORDER_REFLECT # 倒映,abcdefg | gfedcbamn | nmabcd

python 学习笔记 14 -- 常用的时间模块之datetime

书接上文,前面我们讲到<常用的时间模块之time>,这次我们学习datetime -- 日期和时间值管理模块 使用apihelper 查看datetime 模块,我们可以看到简单的几项: date       ---  日期对象,结构为date(year, month, day) time       ---  时间值对象,结构为 time([hour[, minute[, second[, microsecond[, tzinfo]]]]]).时间对象所有的参数都是可选的.tzinfo 可以

python 学习笔记 6 -- 异常处理

当你的程序中出现某些 异常的 状况的时候,异常就发生了.例如,当你想要读某个文件的时候,而那个文件不存在.或者在程序运行的时候,你不小心把它删除了. 那么如果你是在IDE中运行,一个错误发生,异常会被打引出来,这便是未处理异常:当异常发生时,如果没有代码去关注和处理它,这些异常会传给置在Python中的缺省处理,他会输出一些调试信息并且终止运行.如果是在IDE中,这不是什么大事,但是如果是Python程序运行中的异常,它会导致整个程序终止,对于这些情况可以使用异常来处理. 1.try..exce