类反射的四个基本函数

  • hasattr
  • getattr
  • setattr
  • delattr
#反射
class BlackMedium:
feature = 'Ugly'
def __init__(self,name, addr):
self.name = name
self.addr = addr
def sell_house(self):
print('[%s]正在卖房子,xx才买呢'%self.name) def rent_house(self):
print('[%s]正在卖房子,xx才租呢'%self.name) b1 = BlackMedium('万成置地','天路园')
print(b1.__dict__)
print(hasattr(b1,'name'))
print(getattr(b1,'name'))
print(hasattr(b1,'sell_house'))
print(getattr(b1,'sell_house'))
func = getattr(b1,'sell_house')
func()
# print(getattr(b1,'sell_housedfa'))#没有则报错
print(getattr(b1,'sell_housedfa','没有这个属性'))#没有则报错 # b1.sb = True 等同于下面
setattr(b1, 'sb', True)
setattr(b1, 'func', lambda x: x + 1)
setattr(b1, 'func1', lambda self: self.name + 'sb')
print(b1.func(2))
print(b1.func1(b1))
print(b1.__dict__) # del b1.sb 等同于下面
delattr(b1,'sb')
print(b1.__dict__) >>> {'name': '万成置地', 'addr': '天路园'}
True
万成置地
True
<bound method BlackMedium.sell_house of <__main__.BlackMedium object at 0x02F5B9B0>>
[万成置地]正在卖房子,xx才买呢
没有这个属性 3
万成置地sb
{'name': '万成置地', 'addr': '天路园', 'sb': True, 'func': <function <lambda> at 0x00A99AE0>, 'func1': <function <lambda> at 0x00A99C00>}
{'name': '万成置地', 'addr': '天路园', 'func': <function <lambda> at 0x00A99AE0>, 'func1': <function <lambda> at 0x00A99C00>}

反射动态获取模块的方法名

class FtpClient:
def __init__(self,addr):
print('正在连接服务器[%s]' %addr)
self.addr = addr #另外一个模块
#from module import FtpClient
f1=FtpClient('192.168.1.1')
if hasattr(f1,'get'):
func_get= getattr(f1,'get')
func_get()
else:
print('此方法不存在')
print('处理其他逻辑')

_getattr_

class Foo:
x = 1
def __init__(self, y):
self.y = y def __getattr__(self, item):
print("执行_getattr__") f1 = Foo(10)
print(f1.y)
print(getattr(f1,'y'))
f1.sssss#__getattr__调用一个不存在的属性时才会触发 >>>
10
10
执行_getattr__

_delattr_

class Foo:
x = 1
def __init__(self, y):
self.y = y def __delattr__(self, item):
print("执行__delattr__") f1 = Foo(10)
del f1.y #删除时就触发__delattr__
del f1.x #删除时就触发__delattr__ >>>
执行__delattr__
执行__delattr__

_setattr_

class Foo:
x = 1
def __init__(self, y):
self.y = y def __setattr__(self, key, value):
print("执行__setattr__")
# self.key = value#会出现递归错
self.__dict__[key]=value #必须要这么设置 f1 = Foo(10)
print(f1.__dict__)
f1.z = 2
print(f1.__dict__)
  • 利用__setattr__,__getattr__限制类的属性必须是字符串类型
class Foo:
def __init__(self,name):
self.name = name def __getattr__(self,item):
print("你找的属性[%s]不存在"%item) def __setattr__(self, key, value):
print("执行__setattr__", key, value)
if type(value) is str:
print('开始设置')
self.__dict__[key] = value
else:
print('必须是字符串') f1 = Foo("alex") #只有是字符串才能添加到Foo, Foo的属性必须是字符串
f1.age = 19 >>>
执行__setattr__ name alex
开始设置
执行__setattr__ age 19
必须是字符串
{'name': 'alex'}

setattr, __delattr__的实际使用举例

class Foo:
def __init__(self,name):
self.name = name def __getattr__(self,item):
print("你找的属性[%s]不存在"%item) def __setattr__(self, key, value):
print("执行__setattr__", key, value)
if type(value) is str:
print('开始设置')
self.__dict__[key] = value
else:
print('必须是字符串') def __delattr__(self, item):
print("执行__delattr__", item)
#del self.item 不能这么用
self.__dict__.pop(item) f1 = Foo("alex") #只有是字符串才能添加到Foo, Foo的属性必须是字符串
print(f1.__dict__)
del f1.name
print(f1.__dict__)

标准类型的二次包装

class List(list): #基础list类
def append(self, p_object):
if type(p_object) is str:
# list.append(self,p_object)
super().append(p_object)
print("必须追加字符串")
def show_middle(self):
mid_index = int(len(self)/2)
return self[mid_index] l1 = List("hello*world")
l1.append(11111)
l1.append('test')
print(l1) # l2 =list("hello*world")
#
# print(l2,type(l2))
# print(l1,type(l1))
# print(l1.show_middle() >>>
必须追加字符串
['h', 'e', 'l', 'l', 'o', '*', 'w', 'o', 'r', 'l', 'd', 'test']

授权

  • 授权是所有更新的功能都是由新类的某部分来处理,但已存在的功能授权给对象的默认属性
  • 授权的关键就是覆盖__getattr__方法
class Open:
def __init__(self, filename, mode ='r', encoding = 'utf-8'):
# self.filename = filename
self.file=open(filename, mode, encoding=encoding)
self.mode = mode
self.encoding = encoding
def __getattr__(self, item):
print(item, type(item)) #item是个字符串类型,通过字符串得到一个函数,可以通过getattr
return getattr(self.file,item) #返回一个方法 # def read(self):
# pass
# def write(self):
# pass f1=Open('a.txt','w')
print(f1.file)
print(f1.read) #如果类中没有改方法,触发getattr,read传给item sys_f = open('b.txt','w+')
print(getattr(sys_f,'read')) >>>
<_io.TextIOWrapper name='a.txt' mode='w' encoding='utf-8'>
read <class 'str'>
<built-in method read of _io.TextIOWrapper object at 0x001ECDB0>
<built-in method read of _io.TextIOWrapper object at 0x001ECE30>
  • 组合授权
#用组合的方式实现文件的操作,即可以进行文件父类的操作(非继承),又可以定制本地的方法

import time
class Open:
def __init__(self, filename, mode ='r', encoding = 'utf-8'):
# self.filename = filename
self.file=open(filename, mode, encoding=encoding) #一定要用这种方法打开文件
self.mode = mode
self.encoding = encoding def write(self,line):
# 可以定制文件的write方法
t = time.strftime('%Y-%m-%d %X')
# print('--->',line)
self.file.write('%s %s'% (t,line)) def __getattr__(self, item):
# print(item, type(item)) #item是个字符串类型,通过字符串得到一个函数,可以通过getattr
return getattr(self.file,item) #返回一个方法 f1=Open('a.txt','r+')
print(f1.file)
print(f1.read) #如果类中没有改方法,触发getattr,read传给item # sys_f = open('b.txt','w+')
# print(getattr(sys_f,'read')) f1.write('-------------------\n') #写入a.txt
f1.write('CPU负载过高 \n') #写入a.txt
f1.seek(0) #seek(0)(从头开始)
# 基于对位置的seek
# 0,以文件开头,不限定打开方式。其它的两种限定要以b模式打开
# 1, 相对于上次光标停留的位置
# 2,从文件未尾,倒序。位置要用负数表示
print(f1.read())

getattr和getattribute的区别及联系

class Foo:
def __init__(self,x):
self.x = x def __getattr__(self, item):
#只有在getattribute抛出AttributeError才执行
print("执行的是getattr")
# return self.__dict__[item]
def __getattribute__(self, item):
# 默认情况无论是否有该属性都优先执行getattribute
print("执行的是getattribute")
raise AttributeError('跑出异常了,去执行__getattr__')
# 只可以抛出AttributeError才raise到getattr f1 = Foo(10)
#默认情况无论是否有该属性都优先执行getattribute
f1.xxxx

反射的妙用-根据URL执行相应目录下面的函数


data = input('please input address:') #需要输入account/login
array = data.split('/') #分割为account, login
'''
#实现更加URL不同分发到不同的函数去处理
from backend import account
# 等同于 import backend.account
# backend.account.login()
if data == 'account/login':
account.login()
elif data == 'account/logout':
account.logout()
'''
#根据传入的数列的字符串,通过反射动态调用函数
userspace = __import__('backend.'+array[0]) #backend为目录
model = getattr(userspace, array[0]) #需要多一步getattr
#通过getattr传入函数名称的字符串,调用函数
func = getattr(model, array[1])
func() >>>
please input address:admin/index
欢迎登陆后台管理 调用backend目录下admin.py下index函数 admin.py
def index():
print('欢迎登陆后台管理')

Python类总结-反射及getattr,setattr的更多相关文章

  1. isinstance/type/issubclass的用法,反射(hasattr,getattr,setattr,delattr)

    6.23 自我总结 面向对象的高阶 1.isinstance/type/issubclass 1.type 显示对象的类,但是不会显示他的父类 2.isinstance 会显示的对象的类,也会去找对象 ...

  2. python反射hasattr getattr setattr delattr

    反射 : 是用字符串类型的名字 去操作 变量 相比于用eval('print(name)') 留有 安全隐患 反射 就没有安全问题 hasattr 语法: hasattr(object, name)o ...

  3. Python笔记_第四篇_高阶编程_反射_(getattr,setattr,deattr,hasattr)

    1. 元数据和反射概念: 有关程序及其类型的数据成为元数据(metadata),他保存在程序的程序集中. 反射这个词儿听起来比较陌生.程序在运行时,可以查看其它程序集或其本身的元数据.一个运行的程序查 ...

  4. python类的反射使用方法

    曾经,博主的房东养了只金毛叫奶茶,今天就拿它当议题好了. 博主写本文时正在被广州的蚊子围攻. #反射练习 class animal(object): def __init__(self,name,fo ...

  5. Python类(五)-反射

    反射即通过字符串映射或修改程序运行时的状态.属性.方法 有4个方法: hasattr(): hasattr(object,string):object为实例化的对象,string为字符串 判断对象ob ...

  6. python类的反射

    反射 通过字符串映射或者修改程序运行时的状态.属性.方法, 有一下4个方法 小例子--根据用户输入调用方法: class Dog(object): def __init__(self,name): s ...

  7. 反射hasattr; getattr; setattr; delattr

    hasattr(obj,name_str):#判断一个对象obj里面是否有对应的name_str字符串的方法,返回True或者Falsegetattr(obj,name_str):#根据字符串去获取对 ...

  8. 反射(hasattr , getattr, setattr) 输入的字符串用来运行程序

    当用户输入字符串时,不能够用来运行程序 1.使用 hasattr 找出输入的字符串是否在程序内 2.使用 getattr 返回找出字符串对应的函数的内存地址或者变量 3. 使用setattr 添加新的 ...

  9. python 类知识点总结

    python 类知识点总结 面向对象思想: 1.设计的时候,一定要明确应用场景 2.由对象分析定义类的时候,找不到共同特征和技能不用强求 1.简述类.对象.实例化.实例这些名词的含义: 类:从一组对象 ...

随机推荐

  1. goaccess日志分析

    对于nginx日志分析,有很多工具,衡量好坏的标准大概就是三快:安装快,解析快,上手快.满足这三点的goaccess确实是居家必备良药. 话说这个标题其实有点委屈GoAccess了,它是一个日志分析工 ...

  2. CF757 C hash

    一种数字可以变成另一种数,要求每组中变换前后各种数字数量不变,问方案数 对现有每组中的每个数字构造出现在各个组情况的序列,如2 出现在第一组和第二组各一次那么就要加入组别的标号1,2,出现重复次仍要加 ...

  3. [php]unset函数

    unset($var); 释放一个变量空间 unset($var1, $var2...);释放多个变量空间 unset(var['数组元素内容']);释放数组元素 注意: 1.在函数内部释放全局变量和 ...

  4. Node.js的开源博客系统Ghost搭建教程

    准备工作 Node.js版本:0.10.x.0.12.x.4.2.x.安装步骤可参考:Node.js环境搭建 Ghost版本:0.7.4:中文集成版(33.6M),中文标准版(3.39M),英文原版( ...

  5. SDUT 3923

    Description snow 是个热爱打字的家伙,每次敲出更快的速度都会让他很开心.现在,他拿到一篇新的打字文章,已知这篇文章只有 26 个小写英文字母,给出 snow 打出这 26 个英文字母分 ...

  6. sublime格式化css代码插件:css format

    有时会从网上下载一些css压缩文件,打开后所有代码都在一行,不利于阅读,通过css format插件,能快速展开代码,方便阅读. 参考:Sublime Text 上最好用的 CSS 格式化插件 —— ...

  7. 33、re的match和search区别?

    1.match()函数只检测RE是不是在string的开始位置匹配,search()会扫描整个string查找匹配:2.也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功 ...

  8. TypeScript在node项目中的实践

    TypeScript在node项目中的实践 TypeScript可以理解为是JavaScript的一个超集,也就是说涵盖了所有JavaScript的功能,并在之上有着自己独特的语法.最近的一个新项目开 ...

  9. VideoJS 与 Framework7 中 fastclick 冲突问题

    Framework7 由于自动启用  fastclick,会导致在 移动端下使用 video.js,控制条上的 播放和音量按钮 点击的时候会触发两次. 解决办法: 1. 全局禁用 fastclick, ...

  10. TCP 传输控制协议(转)

    开头先说几个协议: IP:网际协议 TCP:传输控制协议 Http:超文本传输协议 AMQP:高级消息队列协议 一:TCP是什么? TCP(Transmission Control Protocol ...