Python全栈之路-Day31

1 反射

反射的精髓是通过字符串去获取对象属性的值

1.1 基于类和对象反射的属性

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/24

# 基于类和对象反射的属性
class People:
    country = 'China'
    def __init__(self,name):
        self.name = name
    def run(self):
        print('%s is running'%self.name)

p = People('egon') # 实例化一个People对象p
print('基于类和对象反射的属性')
# hasattr: 判断类或对象是否存在某个属性,存在返回True,否则返回False
print('hasattr------------>')
print(hasattr(p,'name'))
print(hasattr(People,'name'))
# getattr: 获取类或对象的属性
print('getattr------------->')
print(getattr(p,'run'))
print(getattr(People,'run'))
func = getattr(p,'run')
func()

# hasattr和getattr结合使用
print('hasattr & getattr------------>')
if hasattr(p,'run'):
    func = getattr(p,'run')
    func()

# setattr: 修改或新增类或对象的属性
print('setattr-------------->')
print(p.__dict__)
setattr(p,'name','cobila')  # 用于修改
setattr(p,'age',18)  # 用于新增
print(p.__dict__)

# delattr: 删除类或对象的属性
print('delattr------------->')
print(p.__dict__)
delattr(p,'name')
print(p.__dict__)

1.2 基于当前模块反射的属性

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/24

import sys
x = 1111
class Foo:
    pass

def s1():
    print('s1')
def s2():
    print('s2')

this_module = sys.modules[__name__] # 获取当前模块
print(this_module)
print(hasattr(this_module,'s1'))
print(getattr(this_module,'s1'))  # print(this_module.s1)
print(hasattr(this_module,'s2'))
print(getattr(this_module,'s2'))  # print(this_module.s2)

1.3 反射的应用1

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/24

import sys

def add():
    print('add')
def delete():
    print('delete')
def update():
    print('update')
def get():
    print('get')

this_module = sys.modules[__name__]
func_dict = {'add':add,'delete':delete,'update':update,'get':get}
while True:
    choice = input('>>').strip()
    if hasattr(this_module,choice):
        func_dict[choice]

1.3 反射的应用2

FTP Client

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/24

class FtpClient:
    'ftp客户端,但是还么有实现具体的功能'
    def __init__(self,addr):
        print('正在连接服务器[%s]'%addr)
        self.addr = addr
    # def get(self):
    #     print('get')

FTP Server

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/24

import ftp_client
f1 = ftp_client.FtpClient('192.168.1.1')
if hasattr(f1,'get'):
    func_get = getattr(f1,'get')
    func_get()
else:
    print('Method get not found')

print('处理其他逻辑')  # 不影响其他功能实现

2 类内置attr

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/24

# class __getattr__ __setattr__ __delattr__
class Foo:
    def __init__(self,name,age):
        self.name = name  # 会触发__setattr__
        self.age = age  # 会触发__setattr__

    def __setattr__(self, key, value):
        print('setattr')
        if not isinstance(value,str): # 可以设置类型限制
            raise TypeError("must be str")
        self.__dict__[key] = value

    def __getattr__(self, item):  # 属性不存在时会执行此函数
        print('getattr')

    def __delattr__(self, item):
        print('delattr')
        self.__dict__.pop(item)

f = Foo('egon',18)  # 初始化会触发__setattr__
f.name = 'cobila'   # 会触发__setattr__
print(f.__dict__)
f.xxx            # 找不到xxx属性时会触发__getattr__
del f.age        # 会触发__delattr__
print(f.__dict__)

3 定制自己的数据类型

3.1 继承的方式

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/24

# 定制自己的数据类型 通过继承
class List(list):
    def append(self, p_object):
        if not isinstance(p_object,int):
            raise TypeError('Must be int')
        super().append(p_object)

    def insert(self,index,p_object):
        if not isinstance(p_object, int):
            raise TypeError('Must be int')
        super().insert(index,p_object)

l1 = List([1,2,3])
print(l1)
l1.append(4)
print(l1)
# l1.append('test') # 会抛出TypeError异常
l1.insert(0,5)
# l1.insert(0,'5')  # 会抛出TypeError异常
print(l1)

3.2 授权的方式

#!/usr/bin/env python
# __Author__: "wanyongzhen"
# Date: 2017/4/24

# 定制自己的open函数 不通过继承 通过授权的方式实现定制自己的数据类型
import time
print(time.strftime('%Y-%m-%d %X')) # 打印当前时间
class Open:
    def __init__(self,filepath,mode='r',encoding='utf-8'):
        self.filepath = filepath
        self.mode = mode
        self.encoding = encoding
        self.f = open(filepath,mode,encoding=encoding)
    def write(self,line):
        t = time.strftime('%Y-%m-%d %X')
        self.f.write('%s %s\n'%(line,t))
    def __getattr__(self,item):
        func = getattr(self.f,item)
        return func

f = Open('b.txt','w')
f.write('test write')
f.write('test write')
f.write('test write')
f.close()

f = Open('b.txt','r+')
res = f.read()
print(res)
f.close()

posted on 2017-04-24 16:57  万越天  阅读(117)  评论(0编辑  收藏  举报