面向对象相关,反射

一、其他相关

1、isinstance(obj,cls)

检查是否obj是否是类cls的对象

class Foo(object):
    pass
 
obj = Foo()
 
isinstance(obj, Foo)
View Code

2、issubclass(sub,super)

检查sub类是不是super类的派生类

class Foo(object):
    pass
 
class Bar(Foo):
    pass
 
issubclass(Bar, Foo)
View Code

二、异常的处理

1、异常基础

  在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!

try:
    pass
except Exception,ex:
    pass
View Code

2、异常种类

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
s1 = 'hello'
try:
    int(s1)
except ValueError, e:
    print e
View Code
s1 = 'hello'
try:
    int(s1)
except KeyError,e:
    print '键错误'
except IndexError,e:
    print '索引错误'
except Exception, e:
    print '错误'
View Code

3、异常其他结构  finally

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

4、主动触发异常  raise

try:
    raise Exception('错误了。。。')
except Exception,e:
    print e
View Code

5、自定义异常

class WupeiqiException(Exception):
 
    def __init__(self, msg):
        self.message = msg
 
    def __str__(self):
        return self.message
 
try:
    raise WupeiqiException('我的异常')
except WupeiqiException,e:
    print e
View Code

6、断言

# assert 条件
 
assert 1 == 1
 
assert 1 == 2
View Code

三、反射

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

class Foo(object):
 
    def __init__(self):
        self.name = 'wupeiqi'
 
    def func(self):
        return 'func'
 
obj = Foo()
 
# #### 检查是否含有成员 ####
hasattr(obj, 'name')
hasattr(obj, 'func')
 
# #### 获取成员 ####
getattr(obj, 'name')
getattr(obj, 'func')
 
# #### 设置成员 ####
setattr(obj, 'age', 18)
setattr(obj, 'show', lambda num: num + 1)
 
# #### 删除成员 ####
delattr(obj, 'name')
delattr(obj, 'func')
View Code
class Foo(object):
 
    def __init__(self):
        self.name = 'alex'
 
    def func(self):
        return 'func'
 
obj = Foo()
 
# 访问字段
obj.name
# 执行方法
obj.func()

那么问题来了?
a、上述访问对象成员的 name 和 func 是什么? 
答:是变量名
b、obj.xxx 是什么意思? 
答:obj.xxx 表示去obj中或类中寻找变量名 xxx,并获取对应内存地址中的内容。
c、需求:请使用其他方式获取obj对象中的name变量指向内存中的值 “alex”
print getattr(obj, 'name')

print obj.__dict__['name']

d、比较三种访问方式

  • obj.name
  • obj.__dict__['name']
  • getattr(obj, 'name')

结论:反射是通过字符串的形式操作对象相关的成员。一切事物都是对象!!!

类和模块都是对象

class Provice:
    country = "中国"

    def __init__(self,name):
        temp = "xxx"
        self.name = name

    #类方法
    @classmethod
    def xxoo(cls):
        print("xxoo",cls)
    #静态方法
    @staticmethod
    def xo(arg1,arg2):
        print("xo")
    def show(self):
        pass

Provice.xxoo()

四、设计模式

一、单例模式

单例,顾名思义单个实例。

学习单例之前,首先来回顾下面向对象的内容:

python的面向对象由两个非常重要的两个“东西”组成:类、实例

面向对象场景一:

如:创建三个游戏人物,分别是:

  • 苍井井,女,18,初始战斗力1000
  • 东尼木木,男,20,初始战斗力1800
  • 波多多,女,19,初始战斗力2500
class Person:

    def __init__(self, na, gen, age, fig):
        self.name = na
        self.gender = gen
        self.age = age
        self.fight =fig

    def grassland(self):
        """注释:草丛战斗,消耗200战斗力"""

        self.fight = self.fight - 200

# #####################  创建实例  #####################

cang = Person('苍井井', '女', 18, 1000)    # 创建苍井井角色
dong = Person('东尼木木', '男', 20, 1800)  # 创建东尼木木角色
bo = Person('波多多', '女', 19, 2500)      # 创建波多多角色

面向对象场景二:

如:创建对数据库操作的公共类

  • 增
  • 删
  • 改
  • 查
class DbHelper(object):

    def __init__(self):
        self.hostname = '1.1.1.1'
        self.port = 3306
        self.password = 'pwd'
        self.username = 'root'

    def fetch(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def create(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def remove(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def modify(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

# #### 操作类 ####

db = DbHelper()
db.create()
View Code

实例:结合场景二实现Web应用程序

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server


class DbHelper(object):

    def __init__(self):
        self.hostname = '1.1.1.1'
        self.port = 3306
        self.password = 'pwd'
        self.username = 'root'

    def fetch(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return 'fetch'

    def create(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return 'create'

    def remove(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return 'remove'

    def modify(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return 'modify'


class Handler(object):

    def index(self):
        # 创建对象
        db = DbHelper()
        db.fetch()
        return 'index'

    def news(self):
        return 'news'


def RunServer(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']
    temp = url.split('/')[1]
    obj = Handler()
    is_exist = hasattr(obj, temp)
    if is_exist:
        func = getattr(obj, temp)
        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

对于上述实例,每个请求到来,都需要在内存里创建一个实例,再通过该实例执行指定的方法。

那么问题来了...如果并发量大的话,内存里就会存在非常多功能上一模一样的对象。存在这些对象肯定会消耗内存,对于这些功能相同的对象可以在内存中仅创建一个,需要时都去调用,也是极好的!!!

铛铛 铛铛 铛铛铛铛铛,单例模式出马,单例模式用来保证内存中仅存在一个实例!!!

通过面向对象的特性,构造出单例模式:

# ########### 单例类定义 ###########
class Foo(object):
 
    __instance = None
 
    @staticmethod
    def singleton():
        if Foo.__instance:
            return Foo.__instance
        else:
            Foo.__instance = Foo()
            return Foo.__instance
 
# ########### 获取实例 ###########
obj = Foo.singleton()

对于Python单例模式,创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.singleton() 。

总结:单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费!!!

 

五、特性

   两种特性

形式一:装饰器 + 方法
形式二:property + 方法

class Foo():
    def fun(self):
        print("func")

    @property
    def pp(self):
        return 123

    @pp.setter
    def pp(self,value):
        print(value)
    @pp.deleter
    def pp(self):
        print("del")

obj = Foo()
print(obj.pp)
obj.pp =999
del obj.pp
View Code
class Foo():
    def f1(self):
        return "sadfsdfsdgfds"

    def f2(self,value):
        return "value"

    def f3(self):
        print("fdsfasf")
    xo = property(fget=f1,fset=f2,fdel=f3,doc="我是说明文档")
obj = Foo()
ret = obj.xo
print(ret)
obj.xo =123
del obj.xo
View Code

六、接口

接口起约束作用

抽象类如果没有抽象方法跟普通的类一样

如果抽象类的普通方法跟其他类一样  如果抽象类有抽象方法,其他的类又继承了抽象方法,则那个其他类必须写抽象方法名字一样的方法

classF(metaclass=abc.ABCMeta) 抽象类

  @abc.abstractmethod 抽象方法

 抽象类+抽象抽象方法

抽象类:技能继承又能约束

抽象方法:约束子类必须有这种方法

from abc import ABCMeta
from abc import abstractmethod
class Father(metaclass=ABCMeta):

    @abstractmethod
    def f1(self):pass

    @abstractmethod
    def f2(self):pass


class F1(Father):
    def f1(self): pass

    def f2(self): pass

    def f3(self):
        pass

obj = F1()
View Code

七、继承补充

当未继承object时(经典类):
  一条道走到黑(深度优先)
继承object(新式类):
  顶部最后(广度优先)
===》py27;未继承object;一条道走到黑

class Bar(object):
    def f1(self):
        print('BAR')

class A(Bar):
    def f(self):
        print('A')

class B(Bar):
    def f1(self):
        print('B')

class C(A):
    def f(self):
        print('C')

class D(B):
    def f1(self):
        print('D')

class E(C,D):
    def f(self):
        print('E')

e = E()
e.f1()
View Code

 

posted @ 2016-06-06 11:53  若时光搁浅  阅读(114)  评论(0)    收藏  举报