类反射的四个基本函数

  • 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. C/C++预处理宏的总结

    1.定义顺序的无关性 #define PI 3.14 #define TWO_PI  2*PI 这两句谁前谁后无所谓,因为预处理器不断迭代来实现宏替换,直到源文件中没有宏了才停止. 2. 宏变量变成字 ...

  2. checkbox选择根据后台List数据进行回显

    需求:记住用户已经选择的 checkbox 选项,当用户再次对该 checkbox 进行选择操作时,应对该用户已经选择的 checkbox 选项进行选中操作. 示例代码: checkbox,js遍历后 ...

  3. 2015/9/29 Python基础(20):类的授权

    类的授权 1.包装包装在Python编程世界中时经常会被提到的一个术语.它是一个通用的名字,意思是对一个已存在的对象进行包装,不管它是数据类型,还是一段代码,可以是对一个已存在的对象,增加新的,删除不 ...

  4. What are the advantages of different classification algorithms?

    What are the advantages of different classification algorithms? For instance, if we have large train ...

  5. (3.1)用ictclas4j进行中文分词,并去除停用词

    酒店评论情感分析系统——用ictclas4j进行中文分词,并去除停用词 ictclas4j是中科院计算所开发的中文分词工具ICTCLAS的Java版本,因其分词准确率较高,而备受青睐. 注:ictcl ...

  6. 60、简述 yield和yield from关键字。

    1.可迭代对象与迭代器的区别 可迭代对象:指的是具备可迭代的能力,即enumerable.  在Python中指的是可以通过for-in 语句去逐个访问元素的一些对象,比如元组tuple,列表list ...

  7. E - Travel Cards CodeForces - 847K (思维)

    题目链接:https://cn.vjudge.net/contest/272855#problem/E 题目大意:给你n,a,b,k,f.n代表有n次旅行计划,然后a代表一次单程旅行的车费,b代表从下 ...

  8. RMQ之ST求区间最大值

    题目链接:https://cn.vjudge.net/problem/HRBUST-1188 每一次按照二进制的方式进行更新,二维数组dp [i] [j],i表示下标,j表示从i 开始的往后移动2的j ...

  9. 64_p6

    polkit-kde-5.10.1-1.fc26.x86_64.rpm 12-Jun-2017 13:45 84854 polkit-libs-0.113-8.fc26.i686.rpm 13-Apr ...

  10. tyvj P1050 最长公共子序列

    题目链接:http://tyvj.cn/p/1050 题解: 裸题,只是为了测试LCS模板写对没有…… #include<cstdio> #include<cstring> # ...