2016-01-20_11S_08day

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016-01-20_11S_08day相关的知识,希望对你有一定的参考价值。

一、isinstance 判断对象是否为类的实例

n1 = 10
print isinstance(n1,int)
class A:
   pass
class B(A):
   pass

b= B()
print isinstance(b,B)
print isinstance(b,A)

===================
D:\python\python.exe D:/python_scripts/11S_08day/index.py
True
True
True

注意:1、isinstance用于判断对象是否为类的实例

       2、类为创建对象的类或创建对象的类的基类

 

 issubclass 判断B是否为A的派生类

print issubclass(B,A)
print issubclass(B,int)

==================
True
False

二、异常处理应用场景

异常处理:

1、当网页URL没有被处理的时候返回大黄页(错误);

技术分享

2、如下代码:

技术分享
inpu = raw_input()
data = int(inpu)

如果输入的不是数字,那么就会报错
View Code

那么实际应用中需要考虑到这些可能出现的异常:

如下:

技术分享
try:
    #正常逻辑代码
    inpu = raw_input()
    data = int(inpu)
except Exception,e:
    #逻辑代码块出现错误
    print e
    print "请输入数字"
    #可以将错误信息写入日志,e
########结果如下############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
ddd
invalid literal for int() with base 10: ddd
请输入数字
View Code

但是上述代码没有将错误分门别类:

技术分享
try:
    li = [11,22,33]
    li[100]

except IndexError,e:
    print error,e
except TypeError,e:
    print e
#以后再使用时,先写详细的错误,最后写一个except Exception,e:
View Code

 

三、异常处理之自定义异常

一般异常处理代码块包含如下代码块:

技术分享
try:
    #逻辑代码,链接数据库,执行sql
    pass
except IndexError,e:
    pass
except Exception,e:
    pass
else:
    #逻辑块中未出现异常时执行
    pass
finally:
    #断开链接,释放资源
    #永远执行,逻辑代码执行完成之后
    pass
View Code

那么,异常处理中e是什么?

技术分享
try:
    int(abcde)
except Exception,e:
    #e是对象,是由Exception类创建的
    print e

#######################
class A:
    pass
obj = A()
print obj    #返回对象的内存地址
#######################
#调用__str__方法
class A:
    def __str__(self):
        return sb
obj = A()
print obj

#######结果#############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
invalid literal for int() with base 10: abcde
<__main__.A instance at 0x000000000259A748>
sb
View Code

事实上,e返回的是Exception中的__str__方法,这样的话我们就可以写自己的异常了。

那么如何自定义异常:

技术分享
class CharlesError(Exception):   #自定义类继承Exception类
    def __str__(self):
        return Charles Error
try:
    raise CharlesError()    #触发异常
except Exception,e:
    print e
#########结果#############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
Charles Error
View Code

上述自定义异常是写死了的,如何灵活返回?

技术分享
class CharlesError(Exception):   #自定义类继承Exception类
    def __init__(self,msg=None):
        self.massage = msg
    def __str__(self):
        if self.massage:
            return self.massage
        else:
            return Charles Error

try:
    obj = CharlesError(123)
    raise obj    #触发异常
except Exception,e:
    print e
#########结果#############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
123
View Code

 

四、自定义异常之断言

技术分享
assert 条件    #如果条件满足,不报错,条件不满足,就报错

1、在程序测试的时候使用;
2、满足条件,可以使用程序,不满足,就不可以使用;
3、一般不要使用;
View Code

总结异常处理:

技术分享
try:
    #主代码块
    pass
except KeyError,e:
    #异常时,执行该块
    pass
else:
    #主代码执行完,执行该块
    pass
finally:
    #无论异常与否,最终执行该块
    pass


要求:
    1、熟悉四个代码块的执行流程;
    2、e是调用了Exception类中的__str__方法;
    3、raise触发异常,在做大项目的时候,代码分层之后会用到;
View Code

 

五、反射和普通方式对比(模拟web框架)

先看一个例子,如下:

技术分享
存在两个url文件home.py和account.py
#home.py
#!/usr/bin/env python
# _*_ coding:utf-8 _*_

def dev():
    return result,home.dev

def index():
    return result,home.index

#account.py
#!/usr/bin/env python
# _*_ coding:utf-8 _*_

def login():
    return account.login

def logout():
    return account.logout

index.py文件(如下)调用上述两个文件:
import home,account
print Charles...
url = raw_input(url:)
if url == home/dev:
    ret = home.dev()
    print ret
elif url == home/index:
    ret = home.index()
    print ret
elif url == account/login:
    ret = account.login()
    print ret
else:
    print 404
################结果为#############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
Charles...
url:ddd
404
View Code

但是一个网站存在有大量的url文件,如果全部使用if...else访问处理的话,那么就是很不明智的;

那么如何处理呢???

事实上,web程序存在框架可以处理,常见的有mvc和mtv两张框架,如下图:

技术分享

在python中,如何处理的呢?

技术分享
controller,action = raw_input(url:).split(/)
#如何去找url,使用简单反射代理处理
import home
#action = 字符串
#去某个模块中招函数,字符串为函数名,如果有,则获取函数
func = getattr(home,action)
ret = func()
print ret

#########结果为#############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
url:home/dev
result,home.dev
View Code

六、反射操作中的成员

 反射的执行,有两种方式:

技术分享
a、
import home
home.dev()
s = "dev" ###
home.dev  ###这两种方式不同

b、
import home
func = getattr(home,"dev")
func()
View Code

getattr,setattr,delattr,hasattr的使用(操作内存中某个容器的元素)

技术分享
import home
print dir(home)   #查看模块中存在哪些成员

print hasattr(home,abcd)   #判断函数abcd是否是模块home的成员

print getattr(home,"dev")

setattr(home,Charles,lambda x:x+1)    #相当于在home模块中添加了一个Charles函数


delattr(home,"dev")    #删除dev成员函数(在内存中删除,而不改变文件内容)
print dir(home)

##########结果为#############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
[__builtins__, __doc__, __file__, __name__, __package__, dev, index]
False
<function dev at 0x0000000001E02518>
[Charles, __builtins__, __doc__, __file__, __name__, __package__, index]
View Code

七、反射操作类和对象中的成员

技术分享
class Foo:
    static_name = NB
    def __init__(self):
        self.name = Charles
    def show(self):
        pass

    @staticmethod
    def static_show():
        pass
    @classmethod
    def class_show(cls):
        pass

obj = Foo()
print Foo.__dict__
print Foo.__dict__.keys()   #类中的成员

print obj.__dict__
############结果为############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
{static_show: <staticmethod object at 0x000000000249E318>, __module__: __main__, show: <function show at 0x000000000254C7B8>, static_name: NB, class_show: <classmethod object at 0x000000000249E858>, __doc__: None, __init__: <function __init__ at 0x000000000254C748>}
[static_show, __module__, show, static_name, class_show, __doc__, __init__]
{name: Charles}
View Code

接下来使用getattr和setattr操作对象

技术分享
class Foo:
    static_name = NB
    def __init__(self):
        self.name = Charles
    def show(self):
        pass

    @staticmethod
    def static_show():
        pass
    @classmethod
    def class_show(cls):
        pass

obj = Foo()
print Foo.__dict__
print Foo.__dict__.keys()

print obj.__dict__

print hasattr(obj,name)
print hasattr(obj,show)


##########结果##############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
{static_show: <staticmethod object at 0x000000000258E318>, __module__: __main__, show: <function show at 0x000000000263C7B8>, static_name: NB, class_show: <classmethod object at 0x000000000258E858>, __doc__: None, __init__: <function __init__ at 0x000000000263C748>}
[static_show, __module__, show, static_name, class_show, __doc__, __init__]
{name: Charles}
True    ????为什么
True


因为:#因为是类寻找的话,会在自己的成员中找,而对象寻找的话,会现在自己的内存中找,如果没有找到,会到创建对象的类中找(通过类对象指针)
View Code

八、反射操作中的多层嵌套成员

模块home.py存在如下内容:

技术分享
class Foo:
    static_name = "NB"
    def __init__(self):
        self.name = "Charles"
    def show(self):
        pass
View Code

模块index.py调用home模块

技术分享
import home
cls = getattr(home,"Foo")
print cls

s_name = getattr(cls,static_name)
print s_name

obj = cls()

name = getattr(obj,name)
print name

##########结果为###############
D:\python\python.exe D:/python_scripts/11S_08day/index.py
home.Foo
NB
Charles
View Code

九、动态模块导入

前面的**attr操作,可以根据用户输入不同的url,自动查找指定模块中url函数,那么如果存在大量的URL模块,我们在使用之前是不是都得import一下呢?

事实上,模块也可以通过字符串的方式由用户导入,具体方法如下:

技术分享
import home
module = __import__("home")  #类似于import home as module
controller,action = raw_input("URL:").split(/)
module1 = __import__(controller)

func = getattr(module,action)
ret = func()
print ret
View Code

可以利用动态导入模块的方法完善web框架

技术分享
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
from wsgiref.simple_server import make_server

def RunServer(environ, start_response):
    start_response(200 OK, [(Content-Type, text/html)])
    url = environ[PATH_INFO]
    module_name  = url.split(/)[1]
    function_name =url.split(/)[2]
    module = __import__(module_name)
    is_exist = hasattr(module,function_name)
    if is_exist:
        func = getattr(module,function_name)
        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()
View Code

十、设计模式之单例模式

单例模式,顾名思义就是单个实例

单例模式--->内存中之存在一个实例,如果想要使用类中的功能,只使用这一个实例(内存中的)

看下面的例子:

技术分享
模块userinfo.py内容如下:

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

class SqlHelper:
    def __init__(self):
        self.hostname = 0.0.0.0
        self.port = 3306
        self.user = root
        self.pwd = 123

    def fetch(self):
        pass

    def remove(self):
        pass


def get_user():
    obj = SqlHelper()
    obj.fetch()
    print id(obj)    #对次调用会创建多个实例,刷新会显示不同的id值
    return 1

def del_user():
    obj = SqlHelper()     #此方法和上一个方法中创建的两个实例,在使用完之后,会被python的垃圾回收机制销毁,也就是在调用的时候回分别创建,但是这是没有必要的,那么如何让相同的实例只创建一份呢?如何实现
    obj.remove()
    return 2
View Code

效果如下:

技术分享

 

技术分享

 

下面使用单利模式,使得每次调用时只调用之前实例化的相同的实例

例子如下:

技术分享
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class SqlHelper:
    __static_instance = None
    def __init__(self):
        self.hostname = 0.0.0.0
        self.port = 3306
        self.user = root
        self.pwd = 123

    @classmethod
    def instance(cls):
        if cls.__static_instance:
            return cls.__static_instance
        else:
            cls.__static_instance = SqlHelper()
            return cls.__static_instance

    def fetch(self):
        pass

    def remove(self):
        pass


def get_user():
    obj = SqlHelper.instance()    #创建实例都用类方法
    obj.fetch()
    print id(obj)
    return 1

def del_user():
    obj = SqlHelper.instance()
    obj.remove()
    return 2


print id(SqlHelper.instance())
print id(SqlHelper.instance())
print id(SqlHelper.instance())
print id(SqlHelper.instance())


###这样做在大数据量的时候,所有的数据库,连接都只连接在一个实例,有可能会出现问题,建议在数据量少的时候使用
View Code

效果如下:

技术分享

技术分享

 

如果不使用web框架,多个实例化结果如下:

技术分享
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class SqlHelper:
    __static_instance = None
    def __init__(self):
        self.hostname = 0.0.0.0
        self.port = 3306
        self.user = root
        self.pwd = 123

    @classmethod
    def instance(cls):
        if cls.__static_instance:
            return cls.__static_instance
        else:
            cls.__static_instance = SqlHelper()
            return cls.__static_instance
obj1=SqlHelper.instance()
print id(obj1)
obj2=SqlHelper.instance()
print id(obj2)
View Code

结果如下:

技术分享
D:\python\python.exe D:/python_scripts/11S_08day/单例模式.py
39048904
39048904
View Code

12、socket原理和web框架的实现

使用浏览器模拟客户端,server端代码如下:

技术分享
#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import socket

def main():
    #创建socket对象
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #监听端口
    sock.bind((localhost,8080))
    #开始监听
    sock.listen(5)    #最大连接数

    while True:
        #阻塞,等
        #直到有请求连接
        connection,address = sock.accept()
        #connection,代表客户端socket对象
        #address,客户端IP地址
        buf = connection.recv(1024)
        connection.send("HTTP/1.1 200 OK\r\n\r\n")
        connection.send("Hello,World!")
        connection.close()

if __name__ == __main__:
    main()
View Code

技术分享

简单例子:

server端:

技术分享
#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import socket

obj_server = socket.socket()
obj_server.bind((localhost,8314))
obj_server.listen(5)

while True:
    print writing....
    conn,addr = obj_server.accept()
    print obj_server.getsockname()  #返回服务器的ip和端口
    #最多接受size
    client_data = conn.recv(1024)
    print client_data
    conn.send(不要回答,不要回答,不要回答)    #发送到缓冲区
    #conn.sendall(abc)   #写到缓冲区之后立即发送
    conn.close()    #关闭连接,但是不关闭socket服务
View Code

client端:

技术分享
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket

obj = socket.socket()
obj.connect((localhost,8314))
print obj.getpeername() #返回服务器的ip和端口
obj.send(请占领地球)
server_data = obj.recv(1024)
print server_data
obj.close()    #关闭socket服务
View Code

如何根据用户输入的信息的关键字,返回特定的应答,模拟10086如下:

server端:

技术分享
#!/usr/bin/env python
# -*- coding:utf-8 -*-


import socket

ip_port = (127.0.0.1,8888)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)

while True:
    conn,address =  sk.accept()
    conn.sendall(欢迎致电 10086,请输入1xxx,0转人工服务.)
    Flag = True
    while Flag:
        data = conn.recv(1024)
        if data == exit:
            Flag = False
        elif data == 0:
            conn.sendall(通过可能会被录音.balabala一大推)
        else:
            conn.sendall(请重新输入.)
    conn.close()
View Code

client端:

技术分享
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = (127.0.0.1,8888)
sk = socket.socket()
sk.connect(ip_port)
sk.settimeout(5)

while True:
    data = sk.recv(1024)
    print receive:,data
    inp = raw_input(please input:)
    sk.sendall(inp)
    if inp == exit:
        break

sk.close()
View Code

 

13、socket详细方法

obj_server.setblocking(False):默认在遇到accept或recv的时候回阻塞,但是如果是obj_server.setblocki

以上是关于2016-01-20_11S_08day的主要内容,如果未能解决你的问题,请参考以下文章

JAVA零基础小白学习教程之day08_接口&多态

python2.0_s12_day9_协程&Gevent协程

python—day21

Learn_Day5

Python_Day11_同步IO和异步IO

java基础学习_面向对象(上)03_day08总结