python 面向对象编程 之 反射
1 什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现自省的函数
下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
四个方法的使用演示class BlackMedium:
feature='Ugly'
def __init__(self,name,addr):
self.name=name
self.addr=addr
def sell_house(self):
print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
def rent_house(self):
print('%s 黑中介租房子啦,傻逼才租呢' %self.name)
b1=BlackMedium('万成置地','回龙观天露园')
#检测是否含有某属性
print(hasattr(b1,'name'))
print(hasattr(b1,'sell_house'))
#获取属性
n=getattr(b1,'name')
print(n)
func=getattr(b1,'rent_house')
func()
# getattr(b1,'aaaaaaaa') #报错
print(getattr(b1,'aaaaaaaa','不存在啊'))
#设置属性
setattr(b1,'sb',True)
setattr(b1,'show_name',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.show_name(b1))
#删除属性
delattr(b1,'addr')
delattr(b1,'show_name')
delattr(b1,'show_name111')#不存在,则报错
print(b1.__dict__)
#类也是对象
class Foo(object):
staticField = "old boy"
def __init__(self):
self.name = 'wupeiqi'
def func(self):
return 'func'
@staticmethod
def bar():
return 'bar'
print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')print getattr(Foo,'bar')()#注意有什么不同
#反射当前 模块成员import sys
def s1():
print 's1'
def s2():
print 's2'
this_module = sys.modules[__name__]
hasattr(this_module, 's1')
getattr(this_module, 's2')
new_method_s2=getattr(this_module,'s2')#相当于给函数起了个别名new_method_s2()s2()#输出结果相同 导入其他模块,利用反射查找该模块是否存在某个方法
#!/usr/bin/env python
# -*- coding:utf-8 -*-
def test():
print('from the test')
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
程序目录:
module_test.py
index.py
当前文件:
index.py
"""
import module_test as obj
#obj.test()
print(hasattr(obj,'test'))
getattr(obj,'test')()
反射的好处: 1.实现可插播机制 2.动态导入模块#--------------------------------
__setattr__,__delattr__,__getattr__
class Foo: x = 1
def __init__(self, y): self.y = y
def __getattr__(self, item): print('----> from getattr:你找的属性不存在')
def __setattr__(self, key, value): print('----> from setattr') # self.key=value #这就无限递归了,你好好想想 # self.__dict__[key]=value #应该使用它
def __delattr__(self, item): print('----> from delattr') # del self.item #无限递归了 self.__dict__.pop(item)
# __setattr__添加/修改属性会触发它的执行f1 = Foo(10)print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值f1.z = 3print(f1.__dict__)
# __delattr__删除属性的时候会触发f1.__dict__['a'] = 3 # 我们可以直接修改属性字典,来完成添加/修改属性的操作del f1.aprint(f1.__dict__)
# __getattr__只有在使用点调用属性且属性不存在的时候才会触发f1.xxxxxx
class List(list): # 继承list所有的属性,也可以派生出自己新的,比如append和mid def append(self, p_object): ' 派生自己的append:加上类型检查' if not isinstance(p_object, int): raise TypeError('must be int') super().append(p_object)
@property def mid(self): '新增自己的属性' index = len(self) // 2 return self[index]
l = List([1, 2, 3, 4])print(l)l.append(5)print(l)# l.append('1111111') #报错,必须为int类型
print(l.mid)
# 其余的方法都继承list的l.insert(0, -123)print(l)l.clear()print(l)
class List(list): def __init__(self, item, tag=False): super().__init__(item) self.tag = tag
def append(self, p_object): if not isinstance(p_object, str): raise TypeError super().append(p_object)
def clear(self): if not self.tag: raise PermissionError super().clear()
l = List([1, 2, 3], False)print(l)print(l.tag)
l.append('saf')print(l)
# l.clear() #异常
l.tag = Truel.clear()
# 练习(clear加权限限制)
python 面向对象编程 之 反射的更多相关文章
- python面向对象编程进阶
python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 ...
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
- python 面向对象编程(一)
一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...
- Python面向对象编程指南
Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...
- Python面向对象编程(下)
本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...
- Python 面向对象编程——访问限制
<无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...
- Python 面向对象编程 继承 和多态
Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...
- Python 面向对象编程基础
Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...
- python面向对象编程学习
python面向对象编程 基本概念理解 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...
随机推荐
- php 查看当前页中的post及get数据
file_put_contents("log1209.html",date('Y-m-d H:i:s ')."-----<br>",FILE_APP ...
- nth-child与nth-of-type区别
示例详细理解:nth-child(n)与:nth-of-type(n)区别 childselector:nth-child(index) 1,子选择器(childselector,这里是p选择器)选中 ...
- 多线程 死锁 wait(int i) notifyAll()
public class ThreadDemo5 { public static void main(String[] args){ Pool pool = new Pool(); Productor ...
- 网络层——IP报文头介绍
IP数据包也叫IP报文分组,传输在ISO网络7层结构中的网络层,它由IP报文头和IP报文用户数据组成,IP报文头的长度一般在20到60个字节之间,而一个IP分组的最大长度则不能超过65535个字节. ...
- Win8系统本地连接显示为网络2
Win8系统中,当改变了网络环境,本地连接就会被识别为网络2,网络3等: 如果在一个固定的网络环境中,需要修改此名称,可以打开注册表: [HKEY_LOCAL_MACHINE\SOFTWARE\Mic ...
- 吴裕雄 python神经网络(6)
import randomimport numpy as npnp.random.randint(0,49,3) ##required libarariesimport tensorflow as t ...
- python3.6安装-windows
1.打开python官网 2.找到下载链接 3.选择对应的版本下载 4.下载完成后打开安装包并执行,运行出该界面. 5.这里是安装到C盘上(默认安装) 6.此处为自定义安装 7.选择自定义安装,并全选 ...
- Java中for循环中的的try-catch
异常处理 当for循环遇上try-catch @Test public void forThrow(){ final int size = 6; for (int i=0; i<size; i+ ...
- mysqlli
./configure --with-mysql=/usr/bin/mysql_config \ --with-mysqli=mysqlnd \ --with-pdo-mysql=mysqlnd ht ...
- BufferedReader .BufferedWriter执行文本复制
/** * 需求:演示 BufferedReader 和 BufferedWriter 的使用,复制一个 java 文件 */ package cn.itcast.others.iostream; i ...